Are you set for the next couple hours?
Problem
With quarantine, I have not been leaving the house all that much, so I seem to have lost my intuition about temperature and my habit of always checking the weather in the morning. This has led me to be surprised by how hot/cold it gets if I’ve gone on a long walk or gone grocery shopping as well as when it starts raining before I’ve gotten home. This led me to the idea of a system that when I leave the house, would let me know about weather changes in the 2 following hours without bothering me. During initial discussion, Jet brought up the suggestion of having reminders only if the person isn’t prepared for the weather change as well as a notification if the person forgot a mask.
Solution
To realize my idea, I plan to make a system that would notify you depending on the weather change when you are leaving the house. It would be known if you are leaving the house rather than entering house because the motion sensor would not be triggered. When you open the door, the current weather would be compared to the weather in the next 2 hours and if it will rain, snow, and/or the temperature will change by 5°F or more you’ll be notified. This data would be collected by a python web scraper. For rain or snow, a pitter-patter type sound would be played by the speaker and temperature changes would be signified by the LED strip’s colors. To attract the person’s attention, this would flash the appropriate color of red-orange or blue three times before staying on for about 5 seconds more. These reminders would be noticeable but not a bother if you are already prepared. This is what I want to first accomplish and then will move on to implementing the RFID part as this is most important to me and it is easily usable by everyone and tags would not have to be put on clothes. Additionally, this would be my first time using WiFi on a project, connecting the Arduino to Python, and creating a web scraper, so I want to focus first on doing that well.
To create the system that would only notify the person if they aren’t prepared, I’d put an RFID scanner near the door frame beside the magnetic door switch so that the the tags on clothes could be scanned while you walk by. The same barcodes would be on things that fit the same purpose. For example, all masks would have one code, rain jacket and umbrella would have another, sweatshirts another, and light jackets another. This can be customized per user in the household code so that what they’d wear for certain conditions and the matching codes are associated with just that person. Each person would be differentiated by the RFID card that they carry on them whenever they leave the house, here the CMU ID card. For a full product using this, I’ve found laundry safe RFID tags that were pretty cheap and small so could work really well in this application.
Components I plan to use:
- magnetic door switch
- esp8266 module or board
- speaker
- led strip
- motion sensor
Add ons
- RFID sensor and cards
Pilates buddy
As a person who always sits in front of the monitor 24/7, my colleagues and I started to realize that we are beginning to establish another commonality other than our majors — back pain. Then I started to brainstorm around the problems of keeping up a good posture, and I got an idea of what other exercises require one to be in a straight back position.
Then I thought of pilates. Pilates, an exercise that requires one to not only have a straight back, but also a regulated breathing technique, and I thought making a pilates tracker would fit the agenda of the final crit.
There are two main interactions I am trying to tackle: the back posture and the breathing tempo.
For the back posture algorithm, I thought of manipulating the accelerometer’s XYZ values on each. If each value shifts in an inclined position, then the vibration motor 1 would buzz.
For breathing, two variations would be needed for the vibration: a short breath and a long breath. By having a button, one can change the tempo of the vibration motor 2. The vibration motor will pulsate in a standard breathing tempo.
Then the additional feature would be background music. It will be peaceful, zen music to corporate with one’s respiration as well. This will be done by integrating the mp3 function in the code.
The image on the left would be a more realistic appearance compared to the one on the right. The band will have the accelerometer in the middle, and the two vibration motors on each side.
This is what it would look like as a sketch.
Ambition:
- Developing a UI
- Visualizing the band with real scale components in them
- Other components?
Interactive Restaurant Menu — Still in paper form!
Inspired by the LED bookmarks, I thought of how circuits could be integrated into traditionally paper like things. Restaurants menus have been evolving quite a lot, and I experience this culture shock every time I come back to China: they went from paper menu, to ordering from tablets/ipads, to having customers scanning a QR code to order and pay from their phone in the last few years. As much as I appreciate the convenience, I really enjoy the feeling of flipping through a paper menu.
I understand many pros of having a digital ordering system for the customer end:
-
- saves time for servers & the number of servers needed
- avoid ordering mistakes
- the order directly goes from customers to the kitchen without going through the servers
- customers can see how much they will be spending right away
Adapting such system is costly, but the wide adoption indicates that the productivity beats the cost. However, in the US, we don’t really see restaurants that uses digital ordering system for the customers.
Some AR applications are used for restaurant menus, and there is a restaurant in London named Inamo that has interactive table tops. BUT I’m proposing a interactive menu that is still in the traditional paper form but takes advantage of the digital ordering system.
Say when the customers presses on a dish on the paper menu, the dish he/she want to order lights up. The menu can display how much the customer will be paying. And when the customer finish ordering, he/she hits submit, and the order goes directly to the kitchen. The waiter can then collect the menu away, and the menu will be ready for the next customer to order.
As for components, I think I will need:
-
- conductive tape
- leds (either those flat/sewable leds or some fancier way of lighting things up while maintaining the overall paper like texture)
- digit display/lcd to display price
- a “submit” button
- to select a dish, things that could work: tactile button, switch button, or even faking a button using tape
Class notes, 17 Nov 2020
Interactive jacket project from Baskinger’s Experimental Form class.
Look at the 2019 Final Crit for some good examples on elevator pitches and proposals.
Next Tuesday, 24 Nov, is the last day you can use A10. We’ll make that a work day. Thursday, 26 Nov, no class due to turkey day.
For Thursday, have a proposal posted to the blog’s Final Crit category.
Class notes, 12 Nov 2020
p5.js / arduino
Configure/test p5.js not required for final crit but lets make sure you can use it if you decide to. The NYU ITP instructions are a good guide. Do not use the online p5.js web editor, use local files and a local browser and text editor.
Final Crit
Start thinking about the final crit. We only have one more day to access A10, 24 Nov, and you should have your wish lists ready
For the final crit combine visual, sound, and kinetics with a state machine and sensors to make something more accessible, usable, or uses universal design.
Here’s a rough schedule. On some of the work days I will do a brief lecture based on questions or inspirational projects done in other physical computing projects. The remainder of this time is making up for my not having open-office hours in A10.
- 17 Nov — workshop proposals
- 19 Nov — work day
- 24 Nov — last day in A10
- 26 Nov — vacation
- 1 Dec — work day
- 3 Dec — crit test flight
- 8 Dec — work day
- 10 Dec — final crit
Assignment for Tuesday
Crit warmup: come up with a problem to solve. No need to write code (unless you want to), just a statement of the problem and your solution.
We will discuss these on Tuesday and brainstorm improvements.
Viewing assignment
These are based on the idea of how you can hide/obfuscate the man behind the curtain.
Former FBI Agent Explains How to Read Body Language
Former CIA Operative In Charge of Disguise Explains How Spies Use Disguises (except for the model with a sleeve)
…and debunks spies and disguises in entertainment:
quick reading assignment for 12 Nov
Chapters 11 and 12
Don’t trip on what’s in front of you!
Problem:
People often trip over small objects that are in their path that they may not be expecting, especially if the object isn’t very tall. This is because the object is well below their sight line unless they are looking towards the ground. If someone’s on their phone, they are also more likely to trip over a small object. Blind people also of course have to be able to navigate around things that they cannot see. While they have a cane that will help them to know if something is in front of them by it hitting it, but sounds to notify something within a stride could be helpful.
Proposed Solution:
To help people with this problem, I propose a small wearable device strapped to the ankle that will buzz at different intervals based on how far an object is. This device is made up of a servo motor, ultrasonic distance sensor, accelerometer, and pancake vibration motor. The servo, distance sensor, and accelerometer are all attached. The servo moves such that the accelerometer is level so that the distance sensor is pointed straight ahead. This is important because as you walk, your leg is at various angles and doesn’t stay vertical. The buzzing from the vibration motor is a good way to know how far you are from something because the sound is pretty distinctive and has the added bonus of being able to feel it on your leg. For an actual version of this, I would package this smaller so that it could be actually something small attached to your leg that isn’t cumbersome. This would go on both ankles so that you’d know if something was in your path for sure and not just on one side. I’d also use a bigger vibration motor so that the sound is a bit louder; with this, I could feel it and hear it fine, but if the house was louder, it would’ve been harder to hear. I also wish that I had soldered the leads of the vibration motor while I was in A10 because the wire kept coming loose while trying to take videos of me walking and I’d have to bend down to fix it and then when I stood up, it would come loose again; along the same vein, I wish I had been recording the whole time because a really good example while walking with the all different buzzing intervals happened when I forgot to restart it.
Proof of Concept:
//changed smoothing example from https://www.arduino.cc/en/Tutorial/BuiltInExamples/Smoothing #include <Servo.h> Servo myLittleMotor; const int servoPin = 11; int servoPosition = 120; #include <NewPing.h> const int triggerPin = 8; const int echoPin = 9; int maxDistance = 400; NewPing sonar(triggerPin, echoPin, maxDistance); const int footSize = 25.4;//cm int distance; const int numReadings = 10; int DISTreadings[numReadings]; // the readings from the analog input int readIndex = 0; // the index of the current reading int DISTtotal = 0; // the running total int DISTaverage = 0; // the average const int yPin = A4; int yVal; const int pancakePin = 6; void setup() { myLittleMotor.attach(servoPin); pinMode(yPin, INPUT); pinMode(pancakePin, OUTPUT); Serial.begin(9600); myLittleMotor.write(servoPosition); for (int thisReading = 0; thisReading < numReadings; thisReading++) { DISTreadings[thisReading] = 0; } } void loop() { myLittleMotor.write(servoPosition); yVal = analogRead(yPin); distance = sonar.ping_cm(); // subtract the last reading: DISTtotal = DISTtotal - DISTreadings[readIndex]; // read from the sensor: DISTreadings[readIndex] = distance; // add the reading to the total: DISTtotal = DISTtotal + DISTreadings[readIndex]; // advance to the next position in the array: readIndex = readIndex + 1; // if we're at the end of the array... if (readIndex >= numReadings) { // ...wrap around to the beginning: readIndex = 0; } // calculate the average: DISTaverage = DISTtotal / numReadings; // send it to the computer as ASCII digits //Serial.println(Yaverage); if (yVal > 352 && servoPosition > 0) { servoPosition -= 1; } else if (yVal < 348 && servoPosition < 180) { servoPosition += 1; } if (DISTaverage < (1.5 * footSize)) { //1 footSize past your foot static int start = millis(); //Serial.println("closest"); if ((millis() - start) < 200) { //digitalWrite(speakerPin,HIGH); digitalWrite(pancakePin, HIGH); } else if ((millis() - start) < 400) { digitalWrite(pancakePin, LOW); } else { start = millis(); } } else if (DISTaverage < (1.5 * footSize + footSize)) { static int start2 = millis(); if ((millis() - start2) < 200) { digitalWrite(pancakePin, HIGH); } else if ((millis() - start2) < 600) { digitalWrite(pancakePin, LOW); } else { start2 = millis(); } } else if (DISTaverage < (1.5 * footSize + 2 * footSize)) { static int start3 = millis(); if ((millis() - start3) < 200) { digitalWrite(pancakePin, HIGH); } else if ((millis() - start3) < 1000) { digitalWrite(pancakePin, LOW); } else { start3 = millis(); } } else { //noTone(speakerPin); digitalWrite(pancakePin, LOW); } Serial.print(yVal); Serial.print('\t'); Serial.println(DISTaverage); delay(25); //38.1 //63.1 //88.9 }
Audible Cooking Thermometer
Problem
I always find tracking the internal temperature of the things being cooked tedious . Sometimes I have to stop what I am doing to check on it, sometimes I have to look at it the whole time if the food can easily be overcooked. If I forget to check, there is a risk of overcooking and therefore bad texture and taste.
Solution
A device that actively tracks the internal temperature of the food and reminds the user when needed can solve this problem. The device is composed of a temperature sensor, a transducer speaker, and a screen. The temperature sensor of the device will be stuck into the middle of the meat or broth to measure the rate of rise in temperature.
If the rising rate is too large that might lead to overcooking, the device plays “Mi Re Do” to remind the user to turn down the gas. Text will be displayed on the screen if the user needs further information. In the same fashion, if the rising rate is too small, the device plays “Do Re Mi”. The user can stop the sound by pressing the device. In addition, specific instructions can be set for different foods. For the demo, an reminder to flip the fish for stir-frying salmon comes up when the temperature reaches a specific value. The device will play a melody when the food is cooked when the temperature reaches its ideal value. However, the device will only be successful if the algorithm of the cooking temperature for different foods is well developed.
Proof of Logic
Because I am not sure if the sensor can be used on real meat, and because it will take a longer time, I changed the rate of temperature rise in each cooking stage and did a demonstration with my hand instead. I stimulate the cooking process by holding the temperature sensor and raises its temperature from room temperature (about 23 Celcius) to 32 Celcius.
//libary #include <OneWire.h> #include <DallasTemperature.h> #include "pitches.h" #include <Wire.h> #include <LiquidCrystal_I2C.h> //definition #define ONE_WIRE_BUS 5 #define SPEAKER 7 #define CONFIRM_BUTTON 2 //Attachment OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); LiquidCrystal_I2C screen(0x27, 16, 2); //Global variable float Celcius = 0; float Fahrenheit = 0; float room_temp = 0; int start_time = 0; const bool isInterrupt = true; bool confirmbuttonState = false; bool isDone = false; static const float salmon_flip_over_temp = 28; //This is the default temperature for flipping salmon static const float done_temp = 32; //This is the temperature when the salmon is "cooked". bool flip = false; float last_read = 0; float current_read = 0; float rise_over_time = 0; //Varibles for the timer of recording data, record data every 2 seconds unsigned long clock_data = 0; // variable for timing const int INTERVAL1 = 2000; // milliseconds between updates //Functions void read_temperature() { sensors.requestTemperatures(); Celcius = sensors.getTempCByIndex(0); Fahrenheit = sensors.toFahrenheit(Celcius); Serial.print(" C "); Serial.print(Celcius); Serial.print(" F "); Serial.println(Fahrenheit); } void ConfirmButtonPressed() { if (digitalRead(CONFIRM_BUTTON) == LOW) { confirmbuttonState = true; } } void temp_rise(float rise_over_time, float lowerbound, float upperbound) { if (rise_over_time > upperbound) { screen.clear(); screen.setCursor(3, 0); screen.print("Turn Down"); while (confirmbuttonState == false) { tone(SPEAKER, NOTE_E4, 200); delay(350); tone(SPEAKER, NOTE_D4, 200); delay(350); tone(SPEAKER, NOTE_C4, 200); delay(1000); } confirmbuttonState = false; screen.clear(); } if (rise_over_time < lowerbound) { screen.clear(); screen.setCursor(4, 0); screen.print("Turn Up"); while (confirmbuttonState == false) { tone(SPEAKER, NOTE_C4, 200); delay(350); tone(SPEAKER, NOTE_D4, 200); delay(350); tone(SPEAKER, NOTE_E4, 200); delay(1000); } confirmbuttonState = false; screen.clear(); } } //The song to play when cooking is finished void fly_me_to_the_moon() { tone(SPEAKER, NOTE_C5); delay(500); tone(SPEAKER, NOTE_B4); delay(500); tone(SPEAKER, NOTE_A4); delay(500); tone(SPEAKER, NOTE_G4); delay(250); tone(SPEAKER, NOTE_F4); delay(1000); tone(SPEAKER, NOTE_G4); delay(250); tone(SPEAKER, NOTE_A4); delay(500); tone(SPEAKER, NOTE_C5); delay(500); tone(SPEAKER, NOTE_B4); delay(500); tone(SPEAKER, NOTE_A4); delay(500); tone(SPEAKER, NOTE_G4); delay(500); tone(SPEAKER, NOTE_F4); delay(250); tone(SPEAKER, NOTE_E4); delay(1250); if (confirmbuttonState == true){ return; } noTone(SPEAKER); delay(250); tone(SPEAKER, NOTE_A4); delay(250); tone(SPEAKER, NOTE_G4); delay(500); tone(SPEAKER, NOTE_F4); delay(500); tone(SPEAKER, NOTE_E4); delay(250); tone(SPEAKER, NOTE_D4); delay(1000); tone(SPEAKER, NOTE_E4); delay(250); tone(SPEAKER, NOTE_F4); delay(500); tone(SPEAKER, NOTE_A4); delay(250); tone(SPEAKER, NOTE_F4); delay(250); tone(SPEAKER, NOTE_GS4); delay(750); tone(SPEAKER, NOTE_F4); delay(500); tone(SPEAKER, NOTE_E4); delay(500); tone(SPEAKER, NOTE_D4); delay(250); tone(SPEAKER, NOTE_C4); delay(1750); noTone(SPEAKER); delay(1000); } //This function is called when the "salmon" option is selected void stirfry_salmon() { //check the rate of temperature rise every 2 seconds if (millis() >= clock_data) { sensors.requestTemperatures(); Celcius = sensors.getTempCByIndex(0); current_read = Celcius; rise_over_time = (current_read - last_read) / 2; //Print information onto the lcd screen int minute = (millis() - start_time) / 60000; int second = (millis() - 60000 * minute) / 1000; //Serial.print(minute); //Serial.println(second); screen.setCursor(0, 0); screen.print("Salmon"); screen.setCursor(0, 1); screen.print((String)"Temp:" + current_read + "C"); screen.setCursor(7, 0); screen.print((String)"Time:" + minute + ":" + second); //Check whether it is time to flip the fish if (current_read >= salmon_flip_over_temp && flip == false) { screen.clear(); screen.setCursor(6, 0); screen.print("Flip"); screen.setCursor(7, 1); screen.print("it"); while (confirmbuttonState == false) { tone(SPEAKER, NOTE_C5, 200); delay(350); tone(SPEAKER, NOTE_B4, 200); delay(350); tone(SPEAKER, NOTE_A4, 200); delay(350); tone(SPEAKER, NOTE_G4, 200); delay(350); tone(SPEAKER, NOTE_A4, 200); delay(350); tone(SPEAKER, NOTE_B4, 200); delay(350); tone(SPEAKER, NOTE_C5, 200); delay(1000); } confirmbuttonState = false; screen.clear(); flip = true; } //Checked if the fish is already cooked if (current_read >= done_temp) { screen.clear(); screen.setCursor(5, 0); screen.print("Cooked"); while (confirmbuttonState == false) { fly_me_to_the_moon(); } confirmbuttonState = false; screen.clear(); isDone = true; return; } //Every cooking stage has a different "standard" rate of temperature rise //0-10s The first stage of cooking if (millis() - start_time <= 10000) { temp_rise(rise_over_time, 0.12, 0.7); } //10-16s The second stage of cooking if (millis() - start_time > 10000 && millis() - start_time <= 16000 ) { temp_rise(rise_over_time, 0.12, 0.19); } //16-24s The third stage of cooking if (millis() - start_time > 16000 && millis() - start_time <= 24000 ) { temp_rise(rise_over_time, 0.6, 0.9); } //>24s The fourth stage of cooking if (millis() - start_time > 10000 && millis() - start_time <= 16000 ) { temp_rise(rise_over_time, 0, 0.3); } last_read = current_read; clock_data = millis() + INTERVAL1 ; //Serial.print(Celcius); //Serial.print(" "); Serial.print(current_read); Serial.print(" "); Serial.println(rise_over_time); } } void setup() { //Initialization Serial.begin(9600); sensors.begin(); screen.init(); screen.backlight(); //Setting the pinMode pinMode(CONFIRM_BUTTON, INPUT_PULLUP); //Attach interrupt if (isInterrupt) { attachInterrupt (digitalPinToInterrupt(CONFIRM_BUTTON), ConfirmButtonPressed, FALLING); } //Record the room temperature sensors.requestTemperatures(); Celcius = sensors.getTempCByIndex(0); room_temp = Celcius; last_read = room_temp; //test-field //tone(SPEAKER, NOTE_A4,200); //screen.setCursor(0, 1); //screen.print("2nd row text"); start_time = millis(); } void loop(void) { if (isDone == false) { stirfry_salmon(); } }
”欢迎光临“ A motion sensor that welcomes customers
Years ago(when I was a kid) in China, when you walk into most convenience stores and small shops, an accessory by the door will welcome you by saying “welcome”, and it also serves to notify the store owners that they have customers. I remember when I was a kid, I found it really annoying, because it makes the sound not only when you walk in, but also when you walk out. And if you stand by the door, it will keep ‘welcoming’ you. It’s probably because the accessory sensor only detects for distance, and it’s not smart enough to distinguish when not to make the sound.
Nowadays, I don’t hear it as often, and I’m not sure if it’s because the sensing accessory it too annoying, or simply because people associate this sound with ‘low-end’ stores. But I thought if this sensing accessory could become smarter, maybe it’s not a bad idea to bring it back?
So I added 2 features:
-
- only makes the sound when someone walks in, not out;
- don’t make the sound if the store owner is already by the door or near the door
I initially wanted to use 2 ultrasonic distance sensors(1 to sense the person walking through the door, and another to sense the store owner being nearby the door), but I only had 1 distance sensor, so I used a button to indicate the event of “the owner is nearby the door”.
Input: Button, Photo-resistor, ultrasonic distance sensors
Output: buzzer speaker
I wasn’t able to get the speaker to play “Welcome” in Chinese, but I tried to mimic the tones of the way “Welcome” sounds with these sensing accessories(shoutout to my musically talented friend Michelle).
I used a photoresistor to detect whether the person is going in or out, but this scheme is far from reliable. A real motion sensor can do a much better job than what I have.
#include<Wire.h> // PIN INIT const int SPEAKERPIN = 3; const int TRIGPIN = 4; const int ECHOPIN = 5; const int BUTTONPIN = 7; const int PHOTOPIN = A0; // GLOBAL VARS int distanceThreshold = 4; int prevPhotoVal = 0; int get_distance(){ unsigned long duration; int distance; digitalWrite(TRIGPIN, HIGH); delay(1); digitalWrite(TRIGPIN, LOW); duration = pulseIn(ECHOPIN, HIGH, 20000); distance = duration / 57; // Divide by round-trip microseconds per cm to get cm return distance; } void setup() { Serial.begin(9600); pinMode(SPEAKERPIN, OUTPUT); pinMode(ECHOPIN, INPUT); pinMode(TRIGPIN, OUTPUT); pinMode(PHOTOPIN, INPUT); pinMode(BUTTONPIN, INPUT_PULLUP); } void loop() { int buttonUp = digitalRead(BUTTONPIN); int currPhotoVal = analogRead(PHOTOPIN); int distance = get_distance(); if (distance < distanceThreshold && buttonUp) { if(currPhotoVal > prevPhotoVal) { tone(SPEAKERPIN , 185, 200); delay(200); tone(SPEAKERPIN , 146.83, 200); delay(200); tone(SPEAKERPIN , 185, 200); delay(200); tone(SPEAKERPIN , 146.83, 400); delay(400); } } prevPhotoVal = currPhotoVal; }