Uncategorized – Intro to Physical Computing: Student Work fall 2019 https://courses.ideate.cmu.edu/60-223/f2019/work Intro to Physical Computing: Student Work Thu, 31 Oct 2019 05:01:06 +0000 en-US hourly 1 https://wordpress.org/?v=5.2.20 Team James – Initial Meeting https://courses.ideate.cmu.edu/60-223/f2019/work/team-james-initial-meeting/ Tue, 29 Oct 2019 13:14:31 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8665 Brief introduction

We (Nick, Leland and Jeena) as a team of students of the CMU Introduction to Physical Computing class are required to make an assistive device for an older person. We are assigned to work with James. On October 21th, 2 of our team members Nick and Jeena conducted an interview with James at his house to learn more about him.

Interview agenda

Prior to our interview, we prepared an agenda about the general flow we wanted to have for our interview as well as the types of questions we thought should be answered before we began thinking about project ideas for James. This was our agenda:

Icebreakers/Introductions:

James’ Career and background, his interests

-Each of our majors and backgrounds, some things we like to do for fun or classes we are currently taking at CMU

Logistical Questions:

-Preferred methods of communication

Best times to email James

-General expectations about how often he’d like us to update him

Questions about his daily life:

-Describe a typical day

-Some of his major hobbies

-Locations or activity he visits or performs often

-General nuisances he experiences

-The most annoying thing he’s had to do in the past couple of days

-New things he’s been trying out

-Things he does for fun with other people and who are those people?

-Things he liked to do but no longer does

Questions about James

-Some words to described himself

-His motivations for becoming an Osher student

-His hopes for the project

Interview summary and major takeaways

We arrived at our meeting with few expectations. James was waiting for us outside ready to receive us and right off the bat, he seemed to have some ideas about what kinds of things he thought would be good projects for us to tackle around the house. Before we got down to business, however, we talked for a while about his career at CMU and he in turn asked us about our interests and hobbies. At one point, the conversation turned to James and his wife’s love of frogs as we had noticed earlier a large number of amphibian statues scattered around the porch. He described to us how he had built the porch himself and would often sit outside and read.

As we went on, we learned more about James’ area of research as a physics professor and his frequent Skype calls with scientists at the CERN particle accelerator as well as his attempts to learn piano, German, and French simultaneously. One theme that seemed to come up repeatedly was James’ love for tinkering and working with his hands. He was very familiar with technology of all kinds and was planning on buying a drone later in the year.

Finally, James described to us the two problems that had come to mind as potential project ideas. He led us upstairs and showed us the first one.

James often has to straddle this staircase and lean over the fan to open his window.

Several times a year, James has a open a close a precariously positioned window behind a fan he would use for climate control. To open it, he would have to straddle a very high staircase and lift the heavy window himself (something he continues to do now).

His other major concern was a light switch that was blocked by a dresser. The only access he had to it was through a small hole cut out of the inside of the bureau which was rather awkward to reach when turning off the lights. He had thought there might be a way to create a new remote switch that was easier to reach.

This is the hole cut into the side of his bureau. On the other side is a light switch sandwiched between the furniture and the wall.

 

As we left, we spent some time playing music on the piano and talking to him about his process of learning. He said he loves Baroque, but struggled with learning how to play separate parts of a piece with separate hands.

In general, the interview felt like it went quite well. It was nice to arrive and find that James already had some ideas in mind, however, we were a little worried as we left that nothing had immediately stuck out as a project idea. Though James suggested some himself, with elaborating on the ideas ourselves, the projects initially struck us as too mechanically challenging or tending towards the trivial side.

What we learned about James, however, was invaluable. He’s a maker as well and is excited about being involved in the project. I’m sure if he could have enrolled in 223 himself, he would have and he had no shortage of ideas for his own projects in the future. So we felt like we left with an solid understanding of our customer, we were just missing the perfect project.

Post-interview wrap-up discussion

The meeting followed the agenda as James answered all the questions on the agenda. However, it was hard to come up with some definite possibilities for what to build a device for due to some miscommunication. James signed up to be an Osher student because he thought that he’d be building something, so he had a few ideas in mind . However, these ideas were quite mechanical problems that wouldn’t suit good problems for us to solve electronically.  If we were to do it again, we would make sure to be upfront with what kind of problems we’re looking for.  For example, when he is talking about a daily process of his, we should be suggestive in what-ifs to give him a better picture of what we’re looking for. I believe each member of the team felt the same way about the interview, as we all had trouble finding some good ideas of what to make for James.

]]>
Team Jan – Initial Meeting https://courses.ideate.cmu.edu/60-223/f2019/work/team-jan-initial-meeting/ Tue, 29 Oct 2019 06:15:45 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8662 Intro

On October 22nd, from 9:00a-10:00a, we met Jan in her home to discuss day to day problems that we could help alleviate through the construction of a physical computing device. We learned that Jan often wants to remain physically active, but forgets to take the time to exercise. Because of that, our proposed assistive device by the end of the meeting was a workout tracking and reminding clock.

Agenda

We planned to start off by introducing ourselves and talking a bit about who we are, where we’re from, ect. in order to break the ice. Then we wanted to show Jan the assistive devices we made for ourselves for Project 1, so she would have examples of the kinds of problems we could try to solve with our project, and have an idea of what to expect from the completed project. We wanted to ask questions about her daily life, such as her hobbies and chores, and from there try to find anything in these daily activities that was difficult or inconvenient. Once we discovered an activity that was difficult, we planned to brainstorm possible solutions and discuss them with Jan. After that, we wanted to ask Jan if she had any questions for us about the project such as the timeline, or what would happen at the next meeting in class.

Summary and Takeaways

The meeting with Jan allowed us to gain a better understanding of her life and how we could potentially help improve it.  For the majority of her career, Jan worked a desk job in substance abuse counseling.  Now retired, she mentioned that she enjoys the ability to live a less sedentary lifestyle after years of sitting.   We spent a large part of the meeting discussing the ways in which she remains active.   She mentioned multiple walking routes, weights in the living room, going to the gym, and being busy with everyday errands.  However, she also said that she does not workout as much as she would like to, and her phone is ineffective at reminding her since she can simply swipe away the reminder.   We found this problem to have great potential for an assistive device to help, and ultimately this was largest opportunity we found for a project.

 

Some of the notes we took while talking with Jan. We noted that exercise was important to her.

We proposed a device which Jan could use to track how often she exercised, and which would also remind her to exercise if she hadn’t been as active as she wanted. We suggested something that would fit on her kitchen counter, near her back door, after she mentioned how she normally leaves to exercise through that door. We figured placing the device there would make it easy for Jan to log when she exercises by pushing a button on the device as she leaves the house.

Jan’s kitchen counter by her back door, where she suggested placing the device.

Besides her active lifestyle we learned a lot about Jan’s mindset and what she enjoys doing.  When it comes to technology, Jan is very knowledgable.  She uses one of the recent iPhones, and gave us advice we didn’t know about  the Pittsburgh Transit app.  She adores visiting her grandson and taking care of her cat Alex who loves to socialize and play with the furniture.  We looked for opportunities to solve problems with her cat getting on the furniture and her grandson’s allergies to the cat, but the solutions were largely outside of our abilities.

Thoughts/Discussion

Overall, we all agreed that the meeting went very well. The meeting did follow our agenda for the most part, but we didn’t try to stick to it too strictly so we could allow the conversation to happen naturally. When we left  the meeting we had a pretty good idea of what we wanted to make for our project, and we believe Jan also knew what to expect as we move forward in developing the device. 

If we were to conduct another interview in the future, we would probably try to stress diversity in our initial ideation phase for project ideas. One of the concerning parts of this interview was how quickly we landed on a project idea during our discussion. While this isn’t necessarily a bad thing, we are more likely to have missed a better idea because of this early limitation in scope.

After the meeting, we had a rather specific idea of what this assistive device should be. As such, there aren’t many other questions that we had thought of to ask. We expect though, that as our project develops, there may be additional information that would be helpful.

]]>
Sleep Better Alarm Clock https://courses.ideate.cmu.edu/60-223/f2019/work/sleep-better-alarm-clock/ Thu, 17 Oct 2019 07:42:54 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8512 Overview

An alarm clock that reminds you to get ready for bed, and gives advice for how to improve your sleep.

The alarm clock after you turn off the morning alarm. It displays the date, time, and a message based on the amount of sleep you got that night.

The inside of the alarm clock

The light turns on to signify that the user should get ready for bed. It can be turned off with a button, that also tells the clock the user is going to bed.

Pressing the button again turns off the morning alarm and tells the clock the user has woken up. It then displays a message based on the amount of sleep it tracked for that night.

Process

One of the big decisions I made was not having a way to change the alarm times. I originally planned to have two buttons that when pressed, would allow you to change the alarms with a potentiometer. I quickly realized, however, that I wouldn’t have enough time to implement this and instead decided to just have the alarms hard coded.

Another decision I made was to use an lcd screen to display the messages for how to improve your sleep. I was debating whether to use an lcd screen or receipt printer, and decided to use the lcd screen since it was big enough to display the messages I had in mind and I knew how to use one so I knew it wouldn’t take much time to add.

The final breadboard version on my clock, with two lcd screens.

Highlights:

This was the first version of my alarm clock. It had a real time clock, LED, piezo buzzer, a button, and one lcd screen that displayed the time.

The final version, with everything soldered to a protoboard. The final version had a second lcd screen, another button, a barrel jack, a speaker instead of a buzzer, and used an arduino nano instead of an uno.

The laser cut box I made for the clock, before I but the electronics in. The original top had holes that were too small for the buttons, so I had to recut the top.

Discussion

One of the critiques I received was, “I think that it would be more effective if you could change the sleep interval w/o having to reprogram the entire device.” I agree that this is something that would greatly improve the clock, since when you need to wake up or go to bed changes over time. As I mentioned earlier, I originally planned to include a way to change the alarms but didn’t have enough time to implement it.

Another critique was, “It might be cool to have this track sleep statistics over the course of the week.” I also agree with this critique. I think having advice given based on a pattern of sleep rather than just one night of sleep would be more useful. 

I think it did satisfy my main goals, and I am happy with how it came out. All of the features work the way I intended them to. I did the best I could in the time given, but there is still a lot of room for improvement. I think that the box is a bit big and bulky. I had designed it that way to make sure everything fit inside it, but it is bigger than it needs to be.

I learned a lot from this project, like that I don’t know how to use interrupts. I ran into a problem where the alarms stopped working correctly all of a sudden, so I tried switching to a different library to see if there was a problem with the library I was using. However, I couldn’t figure out how to use the interrupt that the library relied on to set alarms. There are still a lot of things you can do with the arduino that I have yet to learn.

I really enjoyed being able to just make something on my own.  This is the first time I’ve made a device, so it’s really satisfying to have taken an idea and made it into a reality. Since I had come up with the project idea and it was something I could actually use, I was really motivated and excited to work on the project.

If I could have done anything differently, I would have spent more time researching libraries for the real time clock. I went the library used in the first tutorial I found, but there might have been better libraries out there that I could have worked better for my project that I just didn’t know about.

If I have time this semester, I would like to make another iteration. I would add a way to change the time and the alarms, probably with buttons to indicate you want to change an alarm and a potentiometer to change the time. I would also like to make a more complicated sleep tracker that gives advice after a week of tracking your sleep. I would also make the physical clock smaller, since it’s bulky and takes up a lot of room when it isn’t necessary for it to be so big.

Technical Information

Schematic

 

/*
 * Project 2
 * Karen Abruzzo (kabruzzo)
 * Time: two weeks
 *
 * Collaboration:
 * I used code from the example SetAlarms from the DS3231M library as a staring point.
 * https://github.com/SV-Zanshin/DS3231M
 * 
 * Summary: The code sets two alarms that can be turns off with a button. One alarm turns on 
 * an LED to remind you to go to bed, the other plays a sound to wake you up in the morning.
 * There is also a snooze button. The code also tracks your sleep and outputs the current date,
 * time, and advice onto lcd screens.
 * 
 * Inputs:
 * real time clock              | PIN A4, A5
 * button                       | PIN 2
 * button                       | PIN 5
 * 
 * Outputs:
 * lcd screen    | PIN A4, A5
 * lcd screen    | PIN A4, A5
 * speaker       | PIN 4
 * LED           | PIN 3
 */

#include <DS3231M.h>//library for the rtc
#include <Wire.h>//library for i2c communications on analog pins
#include <LiquidCrystal_I2C.h>//library for the lcd screens

//setup the screens
LiquidCrystal_I2C screen1(0x27, 16, 2);
LiquidCrystal_I2C screen2(0x20, 20, 4);
const uint32_t SERIAL_SPEED        = 115200;

//set up pin numbers
const int ALARM_BUT_PIN = 2; 
const int SNOOZE_BUT_PIN = 5;
const int LED_PIN = 3;
const int BUZ_PIN = 4;

//set up global variables
//time you go to bed
int SLEEP_HOUR;
int SLEEP_MIN;
int SLEEP_SEC;
//time you wake up
int WAKE_HOUR;
int WAKE_MIN;
int WAKE_SEC;
//# of snoozes
int SNOOZES = 0;
//amount of time you slept
int HOURS_SLEPT;
int MINS_SLEPT;
int SECS_SLEPT;

DS3231M_Class DS3231M;
const uint8_t  SPRINTF_BUFFER_SIZE =     32; //this is for displaying the time and date properly
char inputBuffer[SPRINTF_BUFFER_SIZE];
bool ALARM = true; //this variable keeps track of which alarm (day or night) is set to go off next. True means the night alarm is set up.
DateTime SETUP_TIME = DateTime(2019, 10, 10, 11, 23, 0);//current time
DateTime NIGHT_ALARM = DateTime(0, 0, 0, 23, 0, 0);//time you want to go to bed
DateTime NIGHT_ALARM2 = DateTime(0, 0, 0, NIGHT_ALARM.hour() - 1, 30, 0);//time nigh alarm will go off
DateTime DAY_ALARM = DateTime(0, 0, 0, 8, 20, 0);//time day alarm will go off

void setup() {
  // put your setup code here, to run once:

//setup pins
  pinMode(ALARM_BUT_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUZ_PIN, OUTPUT);
  Serial.begin(SERIAL_SPEED);

  //setup lcd screens
  screen1.init();
  screen2.init();

  // turn on the backlight to start
  screen1.backlight();
  screen2.backlight();

  // set cursor to home position, i.e. the upper left corner
  screen1.home();
  while (!DS3231M.begin()) {
    Serial.println(F("Unable to find DS3231MM. Checking again in 3s."));
    delay(3000);
  }
  //DS3231M.adjust(SETUP_TIME); //uncomment this line to set the time on the rtc
  DS3231M.setAlarm(minutesHoursMatch, NIGHT_ALARM2); //start the alarm
  //display the date and time
  DateTime now = DS3231M.now();
  sprintf(inputBuffer, "%04d-%02d-%02d", now.year(), now.month(), now.day());
  screen1.clear();
  screen1.home();
  screen2.clear();
  screen2.home();
  screen1.print(inputBuffer);
  Serial.print(inputBuffer);
  Serial.print(" ");
  sprintf(inputBuffer, "%02d:%02d", now.hour(), now.minute());
  screen1.setCursor(0, 1);
  screen1.print(inputBuffer);
  Serial.println(inputBuffer);

}

void loop() {
  // put your main code here, to run repeatedly:
  DateTime sleepTime; //time you go to bed
  DateTime wakeTime; // time you wake up
  DateTime timeSlept; //how long you slept
  DateTime now = DS3231M.now();
  static uint8_t mins;
  if (mins != now.minute()) //every minute, change display so it displays current time
  { 
    sprintf(inputBuffer, "%04d-%02d-%02d", now.year(), now.month(), now.day());
    screen1.clear();
    screen1.home();
    screen1.print(inputBuffer);
    Serial.print(inputBuffer);
    Serial.print(" ");
    sprintf(inputBuffer, "%02d:%02d", now.hour(), now.minute());
    screen1.setCursor(0, 1);
    screen1.print(inputBuffer);
    Serial.println(inputBuffer);
    mins = now.minute();
  }
  if (digitalRead(ALARM_BUT_PIN)) //if the alarm off button is pressed
  {
    delay(200); //debounces button
    SNOOZES = 0; //reset snoozes
    if (ALARM) { //if the alarm that went off was the night alarm
      //turn off alarm, set alarm time to the morning alarm, turn off the LED,
      //set the sleep time and turn off backlight on second lcd screen
      DS3231M.clearAlarm(); 
      DS3231M.setAlarm(minutesHoursMatch, DAY_ALARM);
      ALARM = !ALARM;
      digitalWrite(LED_PIN, 0);
      sleepTime = DS3231M.now();
      SLEEP_HOUR = sleepTime.hour();
      SLEEP_MIN = sleepTime.minute();
      SLEEP_SEC = sleepTime.second();
      screen2.clear();
      screen2.noBacklight();

    }
    else { //if morning alarm just went off
      //turn off alarm, set alarm time to the night alarm, turn off the speaker,
      //set the wakeup time, calculate and display time slept, 
      //display advice depending on amount of time slept
      DS3231M.clearAlarm();
      DS3231M.setAlarm(minutesHoursMatch, NIGHT_ALARM2);
      sprintf(inputBuffer, "%02d:%02d", NIGHT_ALARM.hour(), NIGHT_ALARM.minute());
      ALARM = !ALARM;
      noTone(BUZ_PIN);
      wakeTime = DS3231M.now();
      WAKE_HOUR = wakeTime.hour();
      WAKE_MIN = wakeTime.minute();
      WAKE_SEC = wakeTime.second();

      HOURS_SLEPT = WAKE_HOUR - SLEEP_HOUR;
      MINS_SLEPT = WAKE_MIN - SLEEP_MIN;
      SECS_SLEPT = WAKE_SEC - SLEEP_SEC;

      //account for any negative numbers from the subtraction
      if (SECS_SLEPT < 0)
      {
        MINS_SLEPT -= 1;
        SECS_SLEPT += 60;
      }
      if (MINS_SLEPT < 0)
      {
        HOURS_SLEPT -= 1;
        MINS_SLEPT += 60;
      }
      if (HOURS_SLEPT < 0)
      {
        HOURS_SLEPT += 12;
      }
      Serial.println("time slept:");
      screen2.clear();
      screen2.backlight();
      screen2.home();
      screen2.print("time slept: ");
      sprintf(inputBuffer, "%02d:%02d:%02d", HOURS_SLEPT, MINS_SLEPT, SECS_SLEPT);
      Serial.println(inputBuffer);

      screen2.print(inputBuffer);
      if (HOURS_SLEPT < 8)
      {
        if (HOURS_SLEPT < 5)
        {
          screen2.setCursor(0, 1);
          screen2.print("Try going to bed");
          screen2.setCursor(0, 2);
          screen2.print("early today, you got");
          screen2.setCursor(0, 3);
          screen2.print("very little sleep.");
          Serial.println("Try going to bed early today, you got very little sleep.");
        }
        else
        {
          screen2.setCursor(0, 1);
          screen2.print("You got less than");
          screen2.setCursor(0, 2);
          screen2.print("8 hours, try to get");
          screen2.setCursor(0, 3);
          screen2.print("more sleep.");
          Serial.println("You slept less than 8 hours, try to get more sleep.");
        }
      }

      else if (SLEEP_HOUR != NIGHT_ALARM.hour())
      {
        screen2.setCursor(0, 1);
        screen2.print("You didn't go to bed");
        screen2.setCursor(0, 2);
        screen2.print("on time, try to stay");
        screen2.setCursor(0, 3);
        screen2.print("on schedule.");
        Serial.println("You didn't go to bed on time, try to stay on schedule.");
      }
      else
      {
        screen2.setCursor(0, 1);
        screen2.print("You got a good");
        screen2.setCursor(0, 2);
        screen2.print("amount of sleep,");
        screen2.setCursor(0, 3);
        screen2.print("good job!");
        Serial.println("You got a good amount of sleep, good job!");
      }
    }

  }
  if (digitalRead(SNOOZE_BUT_PIN)) //if snooze button is pressed
  {
    if (DS3231M.isAlarm()) //if an alarm is going off
    {
      if (SNOOZES < 3) //if snooze button has been hit less than 3 times
      {
        delay(200); //debounce button
        //turn off alarm for ten seconds
        DS3231M.clearAlarm(); 
        DS3231M.setAlarm(minutesHoursMatch, (0, 0, 0, now + TimeSpan(0, 0, 10, 0)));
        digitalWrite(LED_PIN, 0);
        noTone(BUZ_PIN);
        SNOOZES += 1;
      }
      else //if snooze button has been hit 3 or more times
      {
        if (ALARM)
        {
          screen2.clear();
          screen2.home();
          screen2.print("You need to go to");
          screen2.setCursor(0, 1);
          screen2.print("bed!");
        }
        else
        {
          screen2.clear();
          screen2.backlight();
          screen2.home();
          screen2.print("You need to go get");
          screen2.setCursor(0, 1);
          screen2.print("up!");

        }

      }


    }
  }
  if (DS3231M.isAlarm()) //if the alarm is going off
  {

    if (ALARM)
    {
      digitalWrite(LED_PIN, 1); //turn on led
    }
    else
    {
      tone(BUZ_PIN, 1000); //play a loud annoying sound
    }


  }
}

 

]]>
The Knock Lock https://courses.ideate.cmu.edu/60-223/f2019/work/the-knock-lock/ Thu, 17 Oct 2019 02:29:52 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8337 Overview:

Description: A device for opening a door using only a combination of knocks by a user on the outside.

Images:

The entire box is about 7″x10″x3″ and easily hangable on most door frames.

The stepper motor’s shaft protrudes from the box where the rope that will attach to the handle is clamped onto the shaft with one half of a shaft connector.

The lock requires both a 12v and 5v power supply. It also features a built-in USB cable for updating the password of the device.

On the back, two metal brackets are used to hang the lock. The stepper motor is directly attached to the left motor to remove any stress on the box while opening the door. On the right, the accelerometer is loosely attached next to a cup for the microphone.

The accelerometer is allowed some freedom in hopes of capturing greater vibrations. The microphone is surrounded by a cup meant to direct surface vibrations from the door directly into the microphone.

Inside the case, a the reset button and wire are on the right with a with the stepper motor on the left and the sensors on the back (bottom). These all run through a protoboard on the top left and then through the Arduino Uno.

Function:

Lock blinks red upon detecting an incorrect combination.

When entering a correct combination (in this case 1,1,2,1), the led goes solid red and then waits for a reset from the white button. This is when a functional stepper motor would open the door.

The lock hangs off the doorframe with a rope attached to the handle to pull it up when necessary. The reset button will release the rope once the user has entered. The white brackets are wide enough to fit most door frames with almost no installation time.

 

Process:

Changing Ideas:

The original idea for my project was a smart pencil case that would keep track of the number of pencils currently in use and remind/warn me about leaving before putting them back.

I took the first week of this project just working on building up a wood and carboard prototype which worked well but was unable to fully replicate the most challenging parts about this project.

The biggest problem in finishing this idea would have been the design and creation of the dispensing mechanism which would likely have been 3D printed and would have been mechanically very difficult to design reliably or comparably to the types of professional dispensers out there right now.

 

Building the Microphone Casing:

I had a rough idea of how to redirect the sound to the microphone. I started with a basic prototype of cardboard.

I then decided to upgrade using a condiments contains which i new would allow for a better seal against the door with more durability.

I then cut a whole and integrated the microphone into the back of my box, surrounding it with tape to insulate it.

Some Highlights:

Mounting the motor properly proved to be a bit of a challenge as it required both finding the right spacers to properly align the motor shaft with the output whole while also drilling the hole correclty so that the motor could screw directly into the metal brackets as opposed to the surrounding wood.

Assembling the entire project into a small box was both one of the most challenging as well as the most rewarding parts of the project. Trying to make the components space efficient and slowly assembling it all piece by piece was really an interesting process. Here the protoboard, LED, sensors, and button are already mounted before the box is assembled.

Discussion:

This was a tumultuous project to say the least. Entering the two week work period, I thought I had an idea of what my final product would be, how I would implement it, and what challenges I would encounter along the way. Of course, most of this thinking was quickly overturned when I decided to pivot to a completely different idea after having spent a week working on my first prototype. After I having spoken with Robert about my initial idea (which was at best contrived to begin with), I came to agree with his assessment that I had underestimated the complexity of designing and 3D printing a mechanical system for vending pencils one at a time from a pencil box. So I began a search for something new.

Looking ahead towards the deadline of this project, knowing I only had a week to create a final prototype, I was pretty sure I wouldn’t. Although I rarely get tripped with up with the technical details of implementing projects like this, there is something especially terrifying about prospect of polishing and packaging my work into something presentable and useful to an audience other than myself. So after having decided on creating a device that would allow me to open a door from the outside without a key, I’m proud to say that for once I didn’t just dive into the coding and circuitry, but instead decided to consider how my device would look physically and what space in the door/entranceway environment it would occupy. This felt like a big step to me and I was quite happy with the solution I came up with to hang the lock from the top of the door. It seemed relatively minimalist with the added advantage of being mechanically suited to the tricky problem of creating enough stable tension to lift a heavy door handle while still listening for and sensing the vibrations on the door. Barring the disappointment I felt with a last-minute malfunctioning stepper motor (and believe I me I was frustrated), I was both pleased and surprised to see a final product that by my normal standards seemed quite refined, compact and cleverly designed. For once I had actually taken the time to focus on the physical implementation first which actually made the rest of the process more of a joy and less stressful. With just a little more time to debug and iterate, I could have improved my current project to be more robust and useful. That being said, I do agree with many of my classmates about what I could have done better in developing The Knock Lock.

There were several critiques that seemed to follow my own line of thinking about my project. To begin with, I absolutely agree that the reliability of a project like this would be a major concern. The sensor I used were not especially sensitive and although I did take some particular care to try and minimize the error and noise of each sensor’s readings, they weren’t perfect implementations yet and the accelerometer especially probably should have been mounted directly to the door instead of relying on the weight of the lock to provide a good contact with the door. If I wanted to keep the lock entirely modular and immediately portable, it wouldn’t have been a bad idea to instead have the lock function by me flicking or sliding the brackets along the top of the door in a certain pattern. It’s not a bad idea, but obviously different from the implementation I was going for here. Further tuning of the lock as well as adding some potentiometers for manual tuning of the tap thresholds of the user would probably help solve this problem. I’m glad that everybody seemed to agree that the redundancy of two type of sensors would help improve the reliability of the lock. They also had similar ideas about where to take the lock from here. Making the microphone/accelerometer package more modular and separate from the control box would allow me to put several of them at different places around the door. This could make opening the door significantly more complicated as the pattern would not take on different options for double and single taps as well as the location of those taps on the outside of the door. This could be a very fun and interesting way to expand the complexity and usefulness of a project like this and I was glad to see that some of the inherent weaknesses of the hardware (low range for tap detection), could be used to create more complex code and project.

In many ways, I think the time crunch for this project was a bit of a blessing. I was not only required to quickly start iterating and implementing on my new idea, but also to think of creative but reasonable ways to deliver a usable product. Looking back, I know now that I should have spent more time during ideation not only thinking about general ideas, but also about the one or two difficult challenges associated with each. Afterwards, I could have done a quick sweep of my ideas to check for their feasibility given the time constraints and expectations of the project. But I was happy with the way I was able to bounce back and create something physical and possibly useable when I was unsure of my ability to make more aesthetically pleasing projects. Figuring out how to implement something as finicky as tap detection with relatively simple components also turned out to be a fun challenge that forced me to go beyond the simple I/O skills associated with Arduino, and with more time, I know I could have made something even better and more easily tunable to the individual cases of the user.

Although I don’t plan on creating any new version of my project, there are some clear improvements that could be made to enhance its performance and usability. To start, it would be better to find a way to attach the accelerometer directly to the to and secure it firmly so it moves as little as possible with reference to the vibration of the door. Moreover, it would be helpful to find a better way of attaching my rope to the stepper motor. Printing a small plastic wheel to attach to the stepper shaft would ensure management of the rope and prevent jamming (an idea I had the intention of completing, but could not before I ran out of time). It would also be helpful to find a way of making The Knock Lock compatible with a wider variety of doors, not just those who’s handles turn upwards. This would probably entail creating a clever attachment (similar to the pully or wheel attached to the stepper), that would fit around the base of the handle and redirect the string around and under the handle, so as the stepper pulls upwards the handle is pulled downwards. One problem with this setup is that is could require a greater torque on the part of the stepper, so careful steps would have to be taken to ensure the radius of the wheel around the handle would be large enough to minimize the force needed to pull the handle. And finally, of course, I would take greater care to continually check the functionality of my components throughout the assembly process so that I am not surprised to find that a single component has broken or been replaced somewhere along the way and hopefully have a less stressful and more enjoyable experience.

Schematic:

Code:

/*The Knock Lock
 * Author: Nicholas Toldalagi 
 * 
 * Acknowledgements: This code uses the AccelStepper library whos trademark is owned
 * by AirSpayce Pty Ltd. and Copyright Mike McCauley. 
 * 
 * Summary: This code is written to run on an Arduino UNO interfacing with an
 * accelerometer and microphone to listen for and detect single and double knocks
 * on the outside of a door to which they are all attached. Upon detecting a specific
 * sequence of single and double knocks, a stepper engages, opening the door handle
 * from aboves.
 * 
 * Inputs: 
 * Arduino pin / input
 * A0           Z-axis XL input (Z_PIN)
 * A1           Microphone analog output (MIC_PIN)
 * 6            Reset Button (RESET_PIN)
 * 
 * OutputsL
 * Arduino pin / output:
 * 2            Step pin for stepper motor driver (STEP_PIN)
 * 3            Direction pin for stepper motor driver (DIR_PIN)
 * 7            Led indicator pin (LED_PIN)
*/
#include <AccelStepper.h>
//Output Pins: 
const int STEP_PIN = 2;
const int DIR_PIN = 3;
const int Z_PIN = A0;

//Input Pins: 
const int MIC_PIN = A1;
const int LED_PIN = 7;
const int RESET_PIN = 6;

//Programming Constants
const int DTAP_COOLDOWN = 115; //Number of loop cycles idle after single tap detection until second tap detection begins.
const int CODE_LENGTH = 4; //Length of door code
const int CODE[CODE_LENGTH] = {1, 1, 2, 1}; // 1 Indicates single tap, 2 indicates double tap, First knock is left digit
const int DTAP_SAMPLING_PERIOD = 1200; //Period after a first tap detected in which a second one could be registered, roughly measured in clock cycles (#of loops)
const int MIC_THRESH_OFFSET = 50; //Relative thresholds to offset bias above or below which a knock is registered (in LSB)
const int XL_THRESH_OFFSET = 4;

//Global Variables
AccelStepper motor(1, STEP_PIN, DIR_PIN);
int mic_min = -1;
int mic_max = -1;
int xl_min = -1;
int xl_max = -1;
int codeIndex = 0;

void setup() {
  //Setting up all sensor pins:
  pinMode(Z_PIN, INPUT);
  pinMode(MIC_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(RESET_PIN, INPUT);
  digitalWrite(RESET_PIN, LOW); //Internal Pull-down resistor used
  
  motor.setMaxSpeed(600);
  motor.setAcceleration(300);
  motor.setCurrentPosition(0);
  motor.moveTo(0);
  while(motor.distanceToGo() != 0){
    motor.run();
  }
  Serial.begin(9600);
  calibrateSensors(); //Sets Mic and XL Bias, need absolute silence and no vibration for this. Takes about 2 seconds
}

void loop() { //Begins continuous listen for correct input combination
  int xl_val = analogRead(Z_PIN);
  int mic_val = analogRead(MIC_PIN);
  
  bool xl_tap = xl_min > xl_val || xl_max < xl_val;
  bool mic_tap = mic_min > mic_val || mic_max < mic_val;
  
  if(xl_tap && mic_tap) { //Needs to be both
    xl_tap = 0;
    mic_tap = 0;
    int dtap = doubleTap();
    
    if(CODE[codeIndex] == dtap) { //Checks registered taps against code
        codeIndex++;
        if(codeIndex >= CODE_LENGTH) { //Reaches the end of the combination, time to open
          openProcedure();
          delay(10000);
          codeIndex = 0;
        }
        
    } else { //Wrong code value
      codeIndex = 0; //Reset index for another try
      digitalWrite(LED_PIN, HIGH);
      delay(500);
      digitalWrite(LED_PIN, LOW); //Cooldown time for another try
    }
  }
}

void calibrateSensors() {
  digitalWrite(LED_PIN, HIGH);
  Serial.println("Begining Calibration, wait 2 seconds...");
  
  int avgXL = 0;
  int avgMic = 0;
  
  for(int i = 0; i < 20; i++){ //Takes average of both sensors when still to figure out the sensor bias offsets
     avgXL += analogRead(Z_PIN);
     avgMic += analogRead(MIC_PIN);
  delay(100);
  }
  
  avgXL = avgXL/20;
  avgMic = avgMic/20;
  mic_min = avgMic - MIC_THRESH_OFFSET; //Calculates range for each sensor
  mic_max = avgMic + MIC_THRESH_OFFSET;
  xl_min = avgXL - XL_THRESH_OFFSET;
  xl_max = avgXL + XL_THRESH_OFFSET;
  digitalWrite(LED_PIN, LOW);
}

int doubleTap() { //Listens for double tap, if double returns 2, if single returns 1
  delay(DTAP_COOLDOWN); //No detection allowed
  
  for(int i = 0; i < DTAP_SAMPLING_PERIOD; i++) { //Detection begins
    int xl_val = analogRead(Z_PIN);
    int mic_val = analogRead(MIC_PIN);
    
    bool micTap = mic_min > mic_val || mic_max < mic_val;
    bool xlTap = xl_min > xl_val || xl_max < xl_val;
    if(xlTap && micTap) { //Need both to register a tap to prevent false positive. 
      delay(DTAP_COOLDOWN);
      return 2;
    }
  } 
  return 1;
}

void openProcedure() { //Opens and waits to close door until user input on reset button
  digitalWrite(LED_PIN, HIGH);
  openDoor();
  while(!digitalRead(RESET_PIN)){
  }
  digitalWrite(LED_PIN, LOW);
  releaseDoor();
}

void openDoor() { //Opens the door
  motor.moveTo(600);
  while(motor.distanceToGo() != 0){
    motor.run();
  }
}

void releaseDoor() { //Releases the door 
  motor.moveTo(0);
  while(motor.distanceToGo() != 0) {
    motor.run();
  }
}

 

 

]]>
The Laundry Puck https://courses.ideate.cmu.edu/60-223/f2019/work/the-laundry-puck/ Wed, 16 Oct 2019 02:09:11 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8335 A simplified  timer for the washing machines in my dorm building.

The puck is a small handheld timer with one button along the top to activate and deactivate it.

Living in a dorm building where the laundry room is at the other end of the hall compared to my apartment, I’m prone to forget my clothes in the washing machine long after they’re done being cleaned. Recently I’ve used a timer on my phone to remind me to pick up my laundry, but occasionally I still forget to set it.

The goal of this project is to make a system that will remind me when my laundry is done, but is also as easy to use, and remember to use as possible. The resultant device is a highly simplified timer. One button press is all that’s needed to activate it, and the timer progress is shown on LEDs under the surface of the button. The timer vibrates to indicate that my laundry is finished, and can be cancelled early by holding down the button for a second or longer.

The internal circuitry of the puck, on the left is a power management circuit, which limits battery drain when the device is off.

Three different levels of the timer. (10 minutes left, 20 minutes left and 30 minutes left, left to right)

Process

The two design considerations which significantly shaped this project were based on the context in which this device would be used. Specifically, this device needed to be portable, so that it could be taken to the laundry room, and the puck was only expected to be used a few times each month. The concerns for portability introduced new challenges to the project. For example, to make the timer portable, it would need to be small and easy to hold. This prompted the simplified rounded design, as well as the need for the circuitry of the device to be miniaturized from a breadboard down to a 40x30mm protoboard.

Furthermore, being portable required the puck to run on battery power, and in an effort to preserve battery power (given the device would be used infrequently), I designed a power management circuit to minimize battery drain between uses.

The initial test setup for the power management circuit. Here the button could turn on the Arduino, and the Arduino could turn itself off.

While the power circuit was relatively simple to implement, many problems emerged from the level of miniaturization required by this project. Specifically, using the ATTiny85 IC in place of the Arduino Uno board introduced a few complications. Interfacing the ATTiny with the NeoPixel LED ring proved to be difficult due to an unnoticed clock-rate conflict, causing the ATTiny to operate 16 times slower than intended. This unintuitive issue was eventually resolved by burning new firmware into the chip, which adjusted its clock rate from the default 1 MHz to the expected 16 MHz.

The LED ring exhibiting erratic behavior, the result of insufficient filtering on the vibration motor, and a clock rate conflict with the ATTiny85.

The most difficult aspect of this miniaturization though, was recreating the circuitry of the prototype device at such a small scale. Given the complexity of the circuit, wiring it onto a small protoboard proved to be a difficult task. Erroneous connections and weak solder joints were common issues, but I was able to track all of these issues down by using the continuity testing features of the multi-meters.

The final circuit board of the TimerPuck. Wiring at this scale proved to be tremendously difficult.

The first test of the circuit after it was fully soldered to a circuit board.

In terms of the physical construction of the puck, I ended up underestimating the size of my circuitry, which meant that the first completed iteration of the Laundry Puck was not fully enclosed within the case designed for it. Thankfully this was only visible from the bottom side, and the button portion still functioned as planned. After taking new measurements of my circuit board, I reprinted the case to be 50% larger, which allowed all the components to fit properly.

The original case design proved to be too small to contain the circuit board and battery.

The puck fully assembled in the small case, performing its first full test.

The new 3D printed case, 50% larger than the original design.

Discussion

Overall, I am mostly satisfied with how this project turned out, though the in-class criticisms do raise some good points which I intend to address. As one commenter stated:

“I am not sure if this is pocket-able, have you also considered fully committing to the jack-o’-lantern aesthetic?”

I agree that, in the state the puck was in for the in-class presentation, it certainly wasn’t ready to be placed in my pocket, given the exposed circuitry. Since then, I’ve 3D printed a larger enclosure though, that makes the puck more visually appealing. The larger case makes the device less pocket-sized than the original version, but considering this was only meant to be portable in that I could bring it with my laundry to the washing machine, I’d argue the size isn’t that much of an issue.

Similarly, another commenter responded as follows:

“Not sure exactly how this would be less effective than a phone timer, given that your phone would also be on you at all times.”

While an understandable critique, I’d have to disagree with this comment, given that the primary motivation behind this project was that timing the laundry with my phone proved to be ineffective. The entire purpose of the project was to replace my hard to use phone timer with something so simple I wouldn’t forget to use it.

So far, I haven’t been able to test the final version of the puck in daily life to see how well it performs, but I’m currently pleased with the simplicity of the device, and expect it will be able to help solve my problem.

Some complications did arise in the construction of this device which proved to be learning experiences. Specifically, while the electronics, and even more so the software proved to be relatively simple to implement, the physical construction of a device meant to be handheld proved to be rather unruly. I had a tendency to underestimate the size of my device, which resulted in it not fitting its original case. While the new case does fit the electronics properly now, it does serve as an excellent lesson on the importance of leaving some wiggle room in a physical design.

Generally I’m mostly satisfied with this project, though if I were to make some improvements, they would mostly be towards further improving the device’s battery life. Given that the original test versions ran an LED ring off of a 9 volt battery, the puck couldn’t be expected to run for much more than two or three cycles on the timer before misbehaving. For this device to be more practical, it would be best if it could be used many times before needing a battery replacement. Possibly, an even better option would be to add a rechargeable battery instead.

Technical Information

  #include <Adafruit_NeoPixel.h>

/* Project Two - Laundry Timer Puck
 * George Ralph (gdr)
 * 8 Hours
 *
 * Collaboration: None
 * 
 * Challenge: Miniaturizing the circuitry for this project to make it fit
 *  in a handheld case proved rather difficult. Eventually, this was resolved
 *  by creating a larger case, and careful soldering to a protoboard.
 * 
 * Next time: I'll leave more room for error in my designs so that components 
 *   aren't too large for their enclosures.
 * 
 * Summary: A timer for the washing machines in my dorm building.
 * 
 * Using a custom power management circuit, the device powers on with the press
 * of the main button. From there, the software displays the current time
 * remaining until the timer is complete. At any point, the user can cancel
 * the timer and turn it off by holding down the main button for one second.
 * 
 *  Inputs: 
 *  
 *  Arduino Pin | Input
 *     1          Button      
 *  
 *  Outputs:
 *  
 *  Arduino pin | Output
 *      2         Vibration Motor
 *      3         NeoPixel LED Ring
 *      4         Power Control Relay
 */
 
const int BUTTON_PIN = 1;
const int MOTOR_PIN = 2;
const int LED_PIN = 3;
const int RELAY_PIN = 4;

const int LED_COUNT = 16;
const int BRIGHTNESS = 10; //20% brightness

//Duration of the timer in minutes
const long duration = 34;
//Duration of the timer in milliseconds
const unsigned long durMillis = duration * 60 * 1000;

unsigned long startTime;
unsigned long buttonDownTime;
bool buttonDown;

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pinMode(MOTOR_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(BRIGHTNESS); // Set BRIGHTNESS to about 1/5 (max = 255)
  
  //Play wind-up animation, and grab start time
  windUp();
  startTime = millis();
}

void loop() {
  //Figure out how long this timer has been running
  unsigned long elapsedTime = millis() - startTime;
  
  //When we pass the duration we need to wait, trigger the alarm
  if(elapsedTime > durMillis) {
    alarm();
  }

  //Compute timeFrac in terms of seconds, since we don't need to be
  //that precise, and we get an overflow otherwise
  int timeFrac = map(elapsedTime / 100, 0, durMillis / 100, 32767, 0);
  drawTimer(timeFrac);

  bool buttonState = !digitalRead(BUTTON_PIN);

  //On buttonDown
  if(buttonState && !buttonDown) {
    buttonDownTime = millis();
  }

  //If the button is down
  if(buttonState) {
    //And it's been down for at least a second
    if(millis() - buttonDownTime >= 1000) {
      //Cancel the timer
      windDown(timeFrac);
      shutDown();
    }
  }
  
  buttonDown = buttonState;
}

/* Called when the timer has finished */
void alarm() {
  digitalWrite(MOTOR_PIN, 1);
  
  //Wait until the button is pressed
  while(digitalRead(BUTTON_PIN)) {
    fillTo(LED_COUNT, strip.Color(255, 0, 0));
    delay(500);

    //Check if the button is pressed halfway through the loop
    if(!digitalRead(BUTTON_PIN)) break;
    
    fillTo(LED_COUNT, strip.Color(255, 255, 255));
    delay(500);
  }

  shutDown();
}

/* Triggers the shutdown relay and cuts power */
void shutDown() {
  digitalWrite(RELAY_PIN, 1);
  delay(500);
}

//Circles the lights in a "wind-up" animation
//Winds up from zero to the fully filled circle
void windUp () {
  digitalWrite(MOTOR_PIN, 1);
  
  for(int i = 0; i <= 255; i++) {
    drawTimer(i * 128);
    delay(5);
  }
  
  digitalWrite(MOTOR_PIN, 0);
}

//Circles the lights in a "wind-down" animation
//Winds down from a specified start time
void windDown (int startTime) {
  digitalWrite(MOTOR_PIN, 1);
  
  for(int i = (startTime / 128); i >= 0; i--) {
    drawTimer(i * 128);
    delay(5);
  }
  
  digitalWrite(MOTOR_PIN, 0);
}

/* Draws the current timer state on the NeoPixel ring 
   Accepts times from 0-32767 */
void drawTimer(int timeFrac) {
  //Get the number of LEDs completely filled
  int filled = timeFrac / (32768L / LED_COUNT);
  //And the level to set the last (fractional) one to
  int frac   = timeFrac % (32768L / LED_COUNT);
  //Map frac to 0-255
  frac = map(frac, 0, (32768L / LED_COUNT), 0, 255);

  //Choose the color for the timer (32767 -> blue, 0 -> red)
  uint32_t color = strip.ColorHSV(max(0, timeFrac - 2048), 255, 255);

  //Draw the filled ones with full brightness
  fillTo(filled, color);

  //Fade in the fractional LED
  color = strip.ColorHSV(max(0, timeFrac - 2048), 255, frac);
  strip.setPixelColor(filled, color);
  
  strip.show();
}
   
/* Fills the first cnt LEDs to the given color */
void fillTo(int cnt, uint32_t color) {
  //Clear whatever was on the strip before
  strip.fill(strip.Color(0, 0, 0));
  
  for(int i = 0; i < cnt; i++) {
    strip.setPixelColor(i, color);
  }
  strip.show();
}

 

]]>
LLS – double transducer https://courses.ideate.cmu.edu/60-223/f2019/work/lls-double-transducer/ Tue, 24 Sep 2019 03:31:03 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8202  

Description:

An infrared sensor detects the distance of an object away from it up to ten centimeters. As the object gets closer to the infrared sensor, a light shines brighter which is measured by a photocell. The measured brightness of the light is used to produce variable sound out of a speaker which gets louder, as the light shines brighter.

**************************************************************************************
56c01359e103486987b9603cc6ecd337

Video: Co-ordination and experimenting with the output group

ULN2803 transistor and the LED with photocell up against it

*************************************************************************************

Discussion:

The first thing we set up and experimented with was an ultrasonic sensor to detect the distance between an object and the sensor. However, the ultrasonic sensor produced less accurate and more noisy data for the arduino to use. Also, in the beginning we used two LEDs which one was green and the other was red. The idea behind this was to implement color coordination with when the object was far away and when the object was close. Red for close, and green for far away. This proved to be ineffective, as it provided more error in measuring light for the photocell. Also, we tested these two LEDs with the ultrasonic sensor, so overall the two provided a bad reading for the photocell compared to the distance being measured. Since we wanted to prioritize the accuracy of this transducer, we decided to replace the two LEDs with one LED shining white light, and an infrared sensor instead of the ultrasonic sensor. The one LED proved to be more reliable, and the infrared sensor was more accurate in detecting the distance we wanted.

The final part of this double transducer was the speaker, and producing a variating volume out of the speaker was a challenge. First, we implemented an ULN2803 transistor which act as a communicator between the speaker and the arduino. The transistor acts as a switch to protect the arduino, as the arduino doesn’t need the external battery that we’ll connect for the speaker. A variating volume requires us to be able to change the voltage going to the speaker as fast as the distance reading changes from the infrared sensor. Changing the frequency of the speaker is easy because the arduino can send signals faster or slower to change frequency, but the arduino can’t change the voltage out of an analog or digital port. We were able to download a library of code to run that would trick the speaker to use a variable voltage, so we mapped the readings from the photocell to the readings that our new library could use. This library did indeed work, but it the speaker produced a very quiet noise that we wouldn’t be able to use. Now, all we needed was an extra voltage source to boost the volume of the speaker, so we added a 6 volt battery for the speaker to use. This produced a measurable volume for the next group to use as an input.

Overall, our double transducer was pretty simple, as we only used the sensors and gadgets that were introduced in class. However, we learned a lot about connecting and experimenting with specific elements with the arduino to optimize the project. This will surely help future projects and the processes we’ll have to go through to build them.

Speaker with additional voltage source attached to it

Picture of the infrared sensor

*******************************************************************************

 

*****************************************************************************************
// Project title: LLS
// Intro to Physical Computing @ Carnegie Mellon University

// Made by Maria Vlachostergiou and Leland Mersky

// Inputs:
// Arduino pin | Input
//     A0        IR sensor
//     A1        Photocell

// Outputs:
// Arduino pin | Output
//     3         white LED
//     5         Speaker

//Summary: Distance TO Light TO Sound
// Step1: We measure proximity. Step 2: We translate proximity into brightness.
// Step 3: We measure the amound of light and we turn it into sound volume and frequency.

***************************************************************************************

// Sound Library & declare a new object
#include <Volume.h>
Volume vol;

// IR SSENSOR for measuring the changing distance from the object
// LED for translating distance into amount of light
// PHOTO_CELL for measuring the amount of light produced
const int IR_SENSOR = A0;
const int PHOTO_CELL = A1;
const int LED = 3;
const int TRANSISTOR = 5;

int distance = 0;
int lightAmount = 0;
int LED_brightness = 0;
int volume = 0;
int frequency = 0;

void setup() {

  Serial.begin(9600);
  vol.begin();

  // INPUTS
  pinMode(IR_SENSOR, INPUT);
  pinMode(PHOTO_CELL, INPUT);
  //OUTPUTS
  pinMode(LED, OUTPUT);
  pinMode(TRANSISTOR, OUTPUT);

}

void loop() {

  // INPUTS VALUES
  distance = analogRead(IR_SENSOR);
  lightAmount = analogRead(PHOTO_CELL);

  // OUTPUTS VALUES
  LED_brightness = map(distance, 0, 300, 0, 255);
  if (distance < 15) {
    digitalWrite(LED, LOW);
  } else {
    analogWrite(LED, LED_brightness);
  }

  // The minimum and maximum lightAmount observed in serial readings were: min=50, max=940
  // Also, the minimun and maximum amount of volume for this speaker are: min=0, max= 256
  volume = map(lightAmount, 50, 940, 0, 256);
  // For different frequencies, the speaker produces different tones of sound. We choose the tones in the frequency range [300,800]
  frequency = map(lightAmount, 50, 940, 300, 800);
  vol.tone(frequency, volume);

  //vol.tone(300, volume);
  //vol.delay(200);
}

// SERIAL MONITOR (INPUTS & OUTPUTS)
Serial.print("The distance from object is: ");
Serial.print(distance);
Serial.print("   The brightness of the LED is: ");
Serial.print(LED_brightness);
Serial.print("   The amount of light is: ");
Serial.print(lightAmount);
Serial.print("   Volume is at: ");
Serial.print(volume);
Serial.print("   Frequency is at: ");
Serial.println(frequency);
Serial.println();

}

 

 

 

 

]]>
Double Transducer: Magnetic Field to Vibration https://courses.ideate.cmu.edu/60-223/f2019/work/double-transducer-magnetic-field-to-vibration/ Mon, 23 Sep 2019 03:17:46 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8114

Photo of the entire project. Magnet switch and magnet on the left, flex sensor and servo in the bottom center, and vibration motor on the right.

The servo and flex sensor mechanism. We extended the arm of the servo to increase the range of motion we bend the flex sensor through.

The transducer in action. A magnet activates the reed switch, which rotates the servo, which flexes the flex sensor, which activates the vibration motor.

Description:

A magnetic switch waits for the presence of a magnet. When the switch is activated, it triggers a motor to spin a lever. The spinning lever twists the flex sensor, which causes it to activate the vibration motor.

Progress:

Testing the US1881 Hall Effect Sensor. We found this sensor to be about as sensitive as the physical reed-switch.

Our first tests of the servo and flex sensor mechanism. We discovered that the values of the flex sensor didn’t cover a very wide range, and were susceptible to noise.

The original vibration motor we chose for our output. The leads proved to be too small to solder easily, so we selected a different motor with larger connections.

Discussion:

We investigated two different methods of detecting a magnetic field for our input: a physical reed switch, and a semiconductor Hall-Effect sensor (US1881). We found both of them to have similar sensitivity, though the Hall-Effect sensor had an interesting latching behavior. Once activated by a magnetic field, it would continue to send an “on” signal until it detected another magnetic field in the other direction. We decided to use the reed switch instead, as it would be simpler for the group providing our input to change the presence of a magnetic field rather than the direction.

Our servo and flex sensor mechanism proved to be an interesting construction challenge. Specifically, we needed a system which could flex the sensor in as wide a range of motion as possible. Because of this, we extended the arm of the servo to rotate over a wider range. We also faced challenges using the flex sensor, from its low range of output values to its fragile design. Specifically, we faced the problem of loose connections on the sensor, as the motion of the system would occasionally pull the sensor pins from the wire plugs they were inserted in. We mostly resolved the connection issue by reconstructing the mechanism with tightly wrapped tape and connections, however the issue of sensitivity remained. To help make our transducer easier to use, we included a calibration dial, to manually determine the set-point at which we consider the sensor flexed. This helped us to avoid making last-minute software changes to adjust the sensor in the case of analog drift.

Our output, a vibration motor proved to be the simplest element of our transducer. We did have some difficulty soldering connections to the part due to its size, however by choosing a different motor, we were able to find one which could be connected to the standard breadboard jumpers. This proved mostly effective until later into in-class testing, when we discovered that the vibration of the motor had managed to loosen its own connections, which we manually reconnected.

Altogether, while our transducer did work as intended, the majority of issues we faced we related to physical problems, rather than electronics or software. Evidently, this shows that the tangible construction of a device can be the limiting factor in terms of its effectiveness. Because of that, we intend to place more attention on the physical layout of our projects in the future to ensure that our electronic and software components can operate without the limitations of poor wiring or construction.

Schematic:

Code:
#include <Servo.h>

/* Project One
 * George Ralph (gdr), Beccy Zheng (rebeccaz)
 * 2 hours 30 minutes
 *
 * Collaboration: Discuss with other groups to coordinate our inputs and outputs.
 * 
 * Challenge: One challenge was attaching the flex sensor to the servo motor.  
 * The flex sensor pins would get detached and read 0 instead of the actual value.
 * Another challenge was getting the vibration motor to work. We originally
 * tried to solder another type of motor, but it was too small to make a connection.
 * We eventually found a larger motor that was easier to use.
 * 
 * Next time: We will plan ahead for how we will assemble the entire project. This
 * includes a better idea of the physical form.
 * 
 * Summary: Magnetic Field -> Flex -> Vibration
 * 
 * We read a magnetic switch and use that value to drive a servo motor. The motor 
 * twists a flex sensor and we use that reading to control a vibration motor. We also
 * have a potentiometer to adjust the threshold of activation we use for the flex sensor.
 * 
 *  Inputs: 
 *  
 *  Arduino Pin | Input
 *     2          Magnet      
 *     A0         Flex Sensor
 *     A1         Potentiometer
 *  
 *  Outputs:
 *  
 *  Arduino pin | Output
 *      3         Servo Motor
 *      4         Vibration Motor
 */

const int MAGNET_PIN    = 2;
const int SERVO_PIN     = 3;
const int VIBRATION_PIN = 4;

const int FLEX_PIN      = A0;
const int POT_PIN       = A1;

Servo servo;

void setup() {
  //Initialize servo connection
  servo.attach(SERVO_PIN);

  //Initialize other IO
  pinMode(MAGNET_PIN,     INPUT);
  pinMode(VIBRATION_PIN, OUTPUT);
  pinMode(FLEX_PIN,       INPUT);
  pinMode(POT_PIN,        INPUT);

  //Initialize the serial connection
  Serial.begin(9600);
}

void loop() {
  //Check the magnet switch
  bool magnetState = digitalRead(MAGNET_PIN);

  //If the switch is on, move the servo to 90 degrees, otherwise to 0
  servo.write(magnetState ? 90 : 0);
  //Wait .5s to give the servo time to move
  delay(500);

  //Read the flex sensor and the dial (setpoint)
  int flexVal = analogRead(FLEX_PIN);
  int dialVal = analogRead(POT_PIN);

  //Print both values as debug information
  Serial.print(flexVal);
  Serial.print("\t");
  Serial.println(dialVal);

  //If the sensor is above the setpoint, turn on the vibration motor
  digitalWrite(VIBRATION_PIN, flexVal > dialVal);
  
}

 

]]>
SleepEZ https://courses.ideate.cmu.edu/60-223/f2019/work/sleepez/ Thu, 29 Aug 2019 13:31:14 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8090

A smart lamp

Title: SleepEZ

Creator: BY- NC-DC

This project is a smart light that reacts to wake and sleep time as well as disturbances. It has a wake mode and a night mode. During night mode, it is able to react to sound disturbances from your phone or IoT devices. In addition to the light changing, the gadget also opens and closes the flower form according to the mode.

 

I liked this project because it was fascinating to me that a product I would usually buy, I can create with Arduino. In addition, I find the form interesting, changing as the modes change. I think it’s a wonderful detail to make experiences more rich, in addition to the function of the device itself.

]]>
Duel https://courses.ideate.cmu.edu/60-223/f2019/work/duel/ Thu, 29 Aug 2019 11:34:24 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8085

Duel by VOLNA

Duel by VOLNAEngineering

Duel is a kinetic light installation composed of rotating disks with a light side and a dark side.  Observing the “idea of conflict acting as a driving force” the disks rotate to “duel” with the light on the opposing side, creating a constant and shifting motion of light and shadow. It is composed of 16 motorized light discs on a 30 meter fixed structure.

What is unclear in the documentation is whether the movement is a specific choreographed order of motion, or if the if the elements react to/sense one another and base their motion off that. I suspect choreography, and in this case adding a sensing/reactive element is a something that think would further push this piece both in its function and its idea conceptually, allowing for elements of surprise as well as a possible interactive audience intervention.

]]>
Third eye for the blind https://courses.ideate.cmu.edu/60-223/f2019/work/third-eye-for-the-blind/ Thu, 29 Aug 2019 02:48:30 +0000 https://courses.ideate.cmu.edu/60-223/f2019/work/?p=8053 created by Muhammed Azhar

 

Short description

  1. Creator’s Vision:
    1. WHAT?  Development of an affordable and more efficient method to help visually impaired people navigate in space with greater speed and confidence.
    2. HOW?  By wearing a technological artefact that detects nearby visual inputs (obstacles) and translates them into haptic and auditory outputs (vibrations & sound).
    3. WHY?  Already existing methods (white cane, dog, smart devices) for visually impaired bodies are either expensive and difficulty to carry with or difficult to be learned and practiced.
  1. Innovation:
    •           ultrasonic waves for the detection of spatial obstacles
    • visual information is encoded and further elaborated by another sense or senses (touch proprioception & audition)
    • wearable, easy to carry

  1. Details: There are five modules across the whole body, all of which are equipped with ultrasonic sensors. Two on the shoulders, two on the knees and one on the hand. Using them one’s can detect the existence of physical materials in a five dimensional view. The distance between the user and the object determines the intensity of the vibration and the rate of sound beeps. The smaller the distance, the more intense the outputs.

                      Arduino pro mini

                      ultrasonic sensors that send and receive waives

                      vibrating motors

                      buzzers

  1. Contributions:
    • Wearable technology for visual impairment
    • An experiential example of sensory substitution and intermodal transfer of information
    • Low-cost/affordable

https://www.youtube.com/watch?v=t3j2ZW9T8CI#action=share

 Sharing my thoughts:

  1. Good points:
    1. The multiple modules make an excellent point as our body’s bones operate like vectors and different body parts may be aligned within different directions.
    2. Vision and touch constitute spatial modalities of perception. That makes it successful to elaborate a visual input through a haptic output
  1. What I would do differently:
    • Add an extra sensor module on the head or the neck
    • Integrate a GPS module
    • Add a sensor that ‘recognizes’ different materials from a distance and uses sound outputs for their perception. 
]]>