Team Dragon
Made by Brian Hernandez, Tiffany Han and Tianyi He
Made by Brian Hernandez, Tiffany Han and Tianyi He
Final Project: Smart Mirror "Connectivity Display and Ambient Lights"
Created: December 5th, 2023
The project that we chose was the Smart Mirror. It merges the functionality of a traditional mirror with modern digital displays. This is for the normal busy person who wants all the information in a quick glance. The main goal behind the creation of smart mirrors is to offer a more interactive and informative experience while maintaining the basic utility of a mirror. Smart mirrors can show real-time information such as weather updates, calendar events, news headlines, and more. In our project the main aspects of the mirror that we will focus on creating a regular mirror into a smart mirror that has a display and led lights. Connectivity will play a pivotal role in our smart mirror project. It will be able to monitor the weather and display it in the mirror.
void setup() {
strip.begin ();
strip.show();
Particle.function("fadeUp", handleFadeUp);
}
void loop() {
if (timerStarted==true){
long timeNow = millis();
long timeElapsed = timeNow - timeStart;
if(timeElapsed < durationFade){
int colorValue = map(timeElapsed, 0, durationFade, 0, 255);
int r=colorValue;
int g=0;
int b=0;
for(int i=0; i<strip.numPixels();i++){
strip.setPixelColor(i,r,g,b);
}
strip.show();
}else{
timerStarted = false;
for(int k=256; k>=0; k--){
for(int i=0;i<strip.numPixels();i++){
strip.setPixelColor(i,0,0,250);
strip.show();
delay(10);
}
}
}
}
else{
for(int i=0;i<strip.numPixels();i++){
strip.setPixelColor(i,10,10,10);
strip.show();
delay(10);
}
}
}
int handleFadeUp(String cmd){
timeStart = millis();
timerStarted =true;
return 1;
}
Click to Expand
Here we started to build upon the code adding a web hook so that we could get the temperature. We at first were failing to get the temperature to work. We also added a sketch of how we wanted to implement the LED lights. One of the things that changed was that we didn't have any neopixels 8 LED lights. So we had to be satisfied with the strip LED lights.
At the end we were happier with the design of the strip LED lights.
int lightPin = D2;
int temperatureThreshold = 35;
void setup() {
Particle.subscribe("hook-response/TemperatureWebhook", myHandler, MY_DEVICES);
pinMode(lightPin, OUTPUT);
}
void loop() {
String data = String(10);
Particle.publish("TemperatureWebhook", data, PRIVATE);
delay(60000);
}
void myHandler(const char *event, const char *data) {
String receivedStr = String(data);
int loc1 = 0;
int loc2 = 0;
loc1 = receivedStr.indexOf("~");
double temperature = receivedStr.substring(0, loc1).toFloat();
adjustLightColor(temperature);
}
void adjustLightColor(double temperature) {
if (temperature < temperatureThreshold) {
analogWrite(lightPin, 0);
} else {
analogWrite(lightPin, 255);
}
}
Click to Expand
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#include "neopixel.h"
#define PIXEL_PIN D3
#define PIXEL_COUNT 62
#define PIXEL_TYPE WS2812
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
bool warm = true;
void getData()
{
// Publish an event to trigger the webhook
Particle.publish( "get-forecast" );
}
void setup() {
strip.begin();
strip.show();
Particle.subscribe("hook-response/get-forecast", handleForecastReceived );
getData();
}
int light_strip(String command)
{
if (warm){
warmer_fade();
return 1;
}
else return -1;
}
//Webhook functions
// This function will handle data received back from the webhook
void handleForecastReceived(const char *event, const char *data) {
// Handle the integration response
String receivedStr = String( data );
int loc1 = 0;
loc1 = receivedStr.indexOf("~");
String temperature_str = receivedStr.substring(0,loc1);
double temperature = (double) String(temperature_str).toFloat();
double humidity = (double) String(receivedStr.substring(loc1+1)).toFloat();
Particle.publish(receivedStr);
}
void cooler_fade(){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, 100, 100); // set a color
strip.show();
delay( 100 );
}
for (int j = 0; j < 3; j++){
for( int k = 0; k <256; k++ ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, k/3, k/2); // set a color
}
strip.show();
delay( 10 );
}
for( int k = 255; k >=0; k-- ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, k/3, k/2 ); // set a color
}
strip.show();
delay( 10 );
}
}
for( int i = 0; i < strip.numPixels(); i++ ){
if (i>0){
strip.setPixelColor(i-1, 0, 0, 0); // set a color
}
strip.setPixelColor(i, 0, 100, 100); // set a color
strip.show();
delay( 100 );
}
}
void warmer_fade(){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 235, 52, 100); // set a color
strip.show();
delay( 100 );
}
for (int j = 0; j < 3; j++){
for( int k = 0; k <256; k++ ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, k/2, 0, k/3); // set a color
}
strip.show();
delay( 10 );
}
for( int k = 255; k >=0; k-- ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, k/2, 0, k/3); // set a color
}
strip.show();
delay( 10 );
}
}
for( int i = 0; i < strip.numPixels(); i++ ){
if (i>0){
strip.setPixelColor(i-1, 0, 0, 0); // set a color
}
strip.setPixelColor(i, 235, 52, 155); // set a color
strip.show();
delay( 100 );
}
}
void loop() {
// uint16_t blue = 0;
// uint16_t red = 0;
// uint16_t green = 0;
// This makes it go brighter and then dim back down
// warmer_fade();
cooler_fade();
}
Click to Expand
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#include "neopixel.h"
#define PIXEL_PIN D3
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812B
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
bool warm;
float limit =72;
float temperature;
void getData()
{
// Publish an event to trigger the webhook
Particle.publish( "get-forecast" );
}
int get_compare(String args){
float set_tmp = String(args).toFloat();
limit = set_tmp;
return 1;
}
void setup() {
strip.begin();
strip.show();
Particle.function("get_compare", get_compare);
Particle.subscribe("hook-response/get-forecast", handleForecastReceived );
getData();
}
//Webhook functions
// This function will handle data received back from the webhook
void handleForecastReceived(const char *event, const char *data) {
// Handle the integration response
String receivedStr = String( data );
int loc1 = 0;
loc1 = receivedStr.indexOf("~");
String temperature_str = receivedStr.substring(0,loc1);
float tmp = String(temperature_str).toFloat();
double humidity = (double) String(receivedStr.substring(loc1+1)).toFloat();
//debugging string-- displays the temperature
Particle.publish(receivedStr);
temperature = tmp;
// if (temperature > (double)72){
// warm = true;
// }
// else{
// warm = false;
// }
}
void cooler_fade(){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, 100, 100); // set a color
strip.show();
delay( 100 );
}
for (int j = 0; j < 3; j++){
for( int k = 0; k <256; k++ ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, k/3, k/2); // set a color
}
strip.show();
delay( 10 );
}
for( int k = 255; k >=0; k-- ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, k/3, k/2 ); // set a color
}
strip.show();
delay( 10 );
}
}
for( int i = 0; i < strip.numPixels(); i++ ){
if (i>0){
strip.setPixelColor(i-1, 0, 0, 0); // set a color
}
strip.setPixelColor(i, 0, 100, 100); // set a color
strip.show();
delay( 100 );
}
}
void warmer_fade(){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 235, 52, 100); // set a color
strip.show();
delay( 100 );
}
for (int j = 0; j < 3; j++){
for( int k = 0; k <256; k++ ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, k/2, 0, k/3); // set a color
}
strip.show();
delay( 10 );
}
for( int k = 255; k >=0; k-- ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, k/2, 0, k/3); // set a color
}
strip.show();
delay( 10 );
}
}
for( int i = 0; i < strip.numPixels(); i++ ){
if (i>0){
strip.setPixelColor(i-1, 0, 0, 0); // set a color
}
strip.setPixelColor(i, 235, 52, 155); // set a color
strip.show();
delay( 100 );
}
}
void loop() {
// This makes it go brighter and then dim back down
if (temperature > limit){
warmer_fade();
}
else{
cooler_fade();
}
// if(warm){
// warmer_fade();
// }
// else{
// cooler_fade();
// }
}
Click to Expand
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#include "neopixel.h"
#define PIXEL_PIN D3
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812B
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
bool warm;
float limit =72;
float temperature;
void getData()
{
// Publish an event to trigger the webhook
Particle.publish( "get-forecast" );
// triggers response to send GET request to api
}
int get_compare(String args){
//function that gets user input for the dividing temperature
float set_tmp = String(args).toFloat();
limit = set_tmp;
return 1;
}
void setup() {
strip.begin();
strip.show();
Particle.function("get_compare", get_compare);
Particle.subscribe("hook-response/get-forecast", handleForecastReceived );
getData();
}
//Webhook functions
// This function will handle data received back from the webhook
void handleForecastReceived(const char *event, const char *data) {
// Handle the integration response
String receivedStr = String( data );
int loc1 = 0;
loc1 = receivedStr.indexOf("~");
String temperature_str = receivedStr.substring(0,loc1);
//a float of temerpature is stored to tmp
float tmp = String(temperature_str).toFloat();
//humidity is stored to a double
double humidity = (double) String(receivedStr.substring(loc1+1)).toFloat();
//DISPLAY TO SCREEN HERE?
//debugging string-- displays the temperature and humidity to console
Particle.publish(receivedStr);
temperature = tmp;
}
void cooler_fade(){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, 100, 100); // set a color
strip.show();
delay( 100 );
}
for (int j = 0; j < 3; j++){
for( int k = 0; k <256; k++ ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, k/3, k/2); // set a color
}
strip.show();
delay( 10 );
}
for( int k = 255; k >=0; k-- ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, k/3, k/2 ); // set a color
}
strip.show();
delay( 10 );
}
}
for( int i = 0; i < strip.numPixels(); i++ ){
if (i>0){
strip.setPixelColor(i-1, 0, 0, 0); // set a color
}
strip.setPixelColor(i, 0, 100, 100); // set a color
strip.show();
delay( 100 );
}
}
void warmer_fade(){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 235, 52, 100); // set a color
strip.show();
delay( 100 );
}
for (int j = 0; j < 3; j++){
for( int k = 0; k <256; k++ ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, k/2, 0, k/3); // set a color
}
strip.show();
delay( 10 );
}
for( int k = 255; k >=0; k-- ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, k/2, 0, k/3); // set a color
}
strip.show();
delay( 10 );
}
}
for( int i = 0; i < strip.numPixels(); i++ ){
if (i>0){
strip.setPixelColor(i-1, 0, 0, 0); // set a color
}
strip.setPixelColor(i, 235, 52, 155); // set a color
strip.show();
delay( 100 );
}
}
void loop() {
// This makes it go brighter and then dim back down
if (temperature > limit){
warmer_fade();
}
else{
cooler_fade();
}
}
Click to Expand
The code of this project is fairly straight forward, as illustrated by this diagram. The code started with just the normal code to light up the neopixels, then we added a function that obtains data from the api. After that, we created two functions, a fade cool and fade warm that would display on repeat. In order to obtain the user data of at what temperature they would like the display to change color, we setup a function to be published to the particle platform, and we do this in the function setup(). After that, we parse the information from the api using a template and the particle integration. (Key component shown in pictures below).
Lastly, we make sure to call the correct neopixel function to display the light as well as write to the display appropriately.
Here we have a final presentation of our project. We have the lights displaying the temperature (42.4 deg F) and the percentage of precipitation (0%). We then typed in our function the number 10. Meaning that if the person believes anything above 10 degrees F is hot then the mirror will turn to the warmer color.
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
#include "Adafruit_ST7789.h"
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "neopixel.h"
#define PIXEL_PIN D3
#define PIXEL_COUNT 62
#define PIXEL_TYPE WS2812B
// You can't really have two of these on the same pins, but this is just to make sure it compiles
// It's not a working example.
// I've removed the examples because it's not possible to have dependencies for individual examples
// and the necessary libraries won't be included and the build will fail. Since other boards like
// the miniTFTWing have their own examples, you should just test this library with those examples.
//Adafruit_ST7789 st7789(&SPI, D2, D3, D4);
#if defined(ARDUINO_FEATHER_ESP32) // Feather Huzzah32
#define TFT_CS 14
#define TFT_RST 15
#define TFT_DC 32
#elif defined(ESP8266)
#define TFT_CS 4
#define TFT_RST 16
#define TFT_DC 5
#else
// For the breakout board, you can use any 2 or 3 pins.
// These pins will also work for the 1.8" TFT shield.
#define TFT_CS D10
#define TFT_RST -1 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC D8
#endif
// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
#define TFT_MOSI 12 // Data out
#define TFT_SCLK 13 // Clock out
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
bool warm;
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
float p = 3.1415926;
float limit =72;
float temperature;
void getData()
{
// Publish an event to trigger the webhook
Particle.publish( "get-forecast" );
// triggers response to send GET request to api
}
int get_compare(String args){
//function that gets user input for the dividing temperature
float set_tmp = String(args).toFloat();
limit = set_tmp;
return 1;
}
void setup(void) {
strip.begin();
strip.show();
Serial.begin(9600);
Serial.print(F("Hello! ST77xx TFT Test"));
// Use this initializer (uncomment) if using a 1.3" or 1.54" 240x240 TFT:
// tft.init(240, 240); // Init ST7789 240x240
// OR use this initializer (uncomment) if using a 1.69" 280x240 TFT:
//tft.init(280, 280); // Init ST7789 280x240
// OR use this initializer (uncomment) if using a 2.0" 320x240 TFT:
//tft.init(240, 320); // Init ST7789 320x240
// OR use this initialhttps://build.particle.io/build/6571ed7b2ae6f2018fb9b700#verifyizer (uncomment) if using a 1.14" 240x135 TFT:
//tft.init(135, 240); // Init ST7789 240x135
// OR use this initializer (uncomment) if using a 1.47" 172x320 TFT:
tft.init(172, 320); // Init ST7789 172x320
// OR use this initializer (uncomment) if using a 1.9" 170x320 TFT:
//tft.init(170, 320); // Init ST7789 170x320
// SPI speed defaults to SPI_DEFAULT_FREQ defined in the library, you can override it here
// Note that speed allowable depends on chip and quality of wiring, if you go too fast, you
// may end up with a black screen some times, or all the time.
//tft.setSPISpeed(40000000);
Serial.println(F("Initialized"));
uint16_t time = millis();
tft.fillScreen(ST77XX_BLACK);
time = millis() - time;
Serial.println(time, DEC);
// tft.drawLine(0, 0, 150, 150, ST77XX_YELLOW);
Particle.function("get_compare", get_compare);
Particle.subscribe("hook-response/get-forecast", handleForecastReceived );
getData();
// testdrawtext("hello", ST77XX_YELLOW);
}
void cooler_fade(){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, 100, 100); // set a color
strip.show();
delay( 100 );
}
for (int j = 0; j < 3; j++){
for( int k = 0; k <256; k++ ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, k/3, k/2); // set a color
}
strip.show();
delay( 10 );
}
for( int k = 255; k >=0; k-- ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 0, k/3, k/2 ); // set a color
}
strip.show();
delay( 10 );
}
}
for( int i = 0; i < strip.numPixels(); i++ ){
if (i>0){
strip.setPixelColor(i-1, 0, 0, 0); // set a color
}
strip.setPixelColor(i, 0, 100, 100); // set a color
strip.show();
delay( 100 );
}
}
void warmer_fade(){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, 235, 52, 100); // set a color
strip.show();
delay( 100 );
}
for (int j = 0; j < 3; j++){
for( int k = 0; k <256; k++ ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, k/2, 0, k/3); // set a color
}
strip.show();
delay( 10 );
}
for( int k = 255; k >=0; k-- ){
for( int i = 0; i < strip.numPixels(); i++ ){
strip.setPixelColor(i, k/2, 0, k/3); // set a color
}
strip.show();
delay( 10 );
}
}
for( int i = 0; i < strip.numPixels(); i++ ){
if (i>0){
strip.setPixelColor(i-1, 0, 0, 0); // set a color
}
strip.setPixelColor(i, 235, 52, 155); // set a color
strip.show();
delay( 100 );
}
}
void loop() {
// This makes it go brighter and then dim back down
if (temperature > limit){
warmer_fade();
}
else{
cooler_fade();
}
}
//Webhook functions
// This function will handle data received back from the webhook
void handleForecastReceived(const char *event, const char *data) {
// Handle the integration response
String receivedStr = String( data );
Particle.publish(receivedStr);
int loc1 = 0;
loc1 = receivedStr.indexOf("~");
String temperature_str = receivedStr.substring(0,loc1);
String humidity_str = receivedStr.substring(loc1+1);
//a float of temerpature is stored to tmp
float tmp = String(temperature_str).toFloat();
//humidity is stored to a double
double humidity = (double) String(receivedStr.substring(loc1+1)).toFloat();
char temperature_chars[5];
char humidity_chars[5];
temperature_str.toCharArray(temperature_chars, 5);
humidity_str.toCharArray(humidity_chars, 5);
//DISPLAY TO SCREEN HERE?
testdrawtext(0, 0, 7, temperature_chars, ST77XX_WHITE);
tft.print("F\n\n");
tft.print(humidity_chars);
tft.print("%");
//debugging string-- displays the temperature and humidity to console
temperature = tmp;
}
void testlines(uint16_t color) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, 0, x, tft.height()-1, color);
delay(0);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(0, 0, tft.width()-1, y, color);
delay(0);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
delay(0);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(tft.width()-1, 0, 0, y, color);
delay(0);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, tft.height()-1, x, 0, color);
delay(0);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
delay(0);
}
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
delay(0);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
delay(0);
}
}
void testdrawtext(uint16_t x, uint16_t y, uint16_t size, char *text, uint16_t color) {
tft.setCursor(x, y);
tft.setTextColor(color);
tft.setTextWrap(true);
tft.setTextSize(size);
tft.print(text);
}
void testfastlines(uint16_t color1, uint16_t color2) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t y=0; y < tft.height(); y+=5) {
tft.drawFastHLine(0, y, tft.width(), color1);
}
for (int16_t x=0; x < tft.width(); x+=5) {
tft.drawFastVLine(x, 0, tft.height(), color2);
}
}
void testdrawrects(uint16_t color) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
}
}
void testfillrects(uint16_t color1, uint16_t color2) {
tft.fillScreen(ST77XX_BLACK);
for (int16_t x=tft.width()-1; x > 6; x-=6) {
tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
}
}
void testfillcircles(uint8_t radius, uint16_t color) {
for (int16_t x=radius; x < tft.width(); x+=radius*2) {
for (int16_t y=radius; y < tft.height(); y+=radius*2) {
tft.fillCircle(x, y, radius, color);
}
}
}
void testdrawcircles(uint8_t radius, uint16_t color) {
for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
tft.drawCircle(x, y, radius, color);
}
}
}
void testtriangles() {
tft.fillScreen(ST77XX_BLACK);
uint16_t color = 0xF800;
int t;
int w = tft.width()/2;
int x = tft.height()-1;
int y = 0;
int z = tft.width();
for(t = 0 ; t <= 15; t++) {
tft.drawTriangle(w, y, y, x, z, x, color);
x-=4;
y+=4;
z-=4;
color+=100;
}
}
void testroundrects() {
tft.fillScreen(ST77XX_BLACK);
uint16_t color = 100;
int i;
int t;
for(t = 0 ; t <= 4; t+=1) {
int x = 0;
int y = 0;
int w = tft.width()-2;
int h = tft.height()-2;
for(i = 0 ; i <= 16; i+=1) {
tft.drawRoundRect(x, y, w, h, 5, color);
x+=2;
y+=3;
w-=4;
h-=6;
color+=1100;
}
color+=100;
}
}
void tftPrintTest() {
tft.setTextWrap(false);
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(0, 30);
tft.setTextColor(ST77XX_RED);
tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ST77XX_YELLOW);
tft.setTextSize(2);
tft.println("Hello World!");
tft.setTextColor(ST77XX_GREEN);
tft.setTextSize(3);
tft.println("Hello World!");
tft.setTextColor(ST77XX_BLUE);
tft.setTextSize(4);
tft.print(1234.567);
delay(1500);
tft.setCursor(0, 0);
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_WHITE);
tft.setTextSize(0);
tft.println("Hello World!");
tft.setTextSize(1);
tft.setTextColor(ST77XX_GREEN);
tft.print(p, 6);
tft.println(" Want pi?");
tft.println(" ");
tft.print(8675309, HEX); // print 8,675,309 out in HEX!
tft.println(" Print HEX!");
tft.println(" ");
tft.setTextColor(ST77XX_WHITE);
tft.println("Sketch has been");
tft.println("running for: ");
tft.setTextColor(ST77XX_MAGENTA);
tft.print(millis() / 1000);
tft.setTextColor(ST77XX_WHITE);
tft.print(" seconds.");
}
void mediabuttons() {
// play
tft.fillScreen(ST77XX_BLACK);
tft.fillRoundRect(25, 10, 78, 60, 8, ST77XX_WHITE);
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_RED);
delay(500);
// pause
tft.fillRoundRect(25, 90, 78, 60, 8, ST77XX_WHITE);
tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_GREEN);
tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_GREEN);
delay(500);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_BLUE);
delay(50);
// pause color
tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_RED);
tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_RED);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_GREEN);
}
Click to Expand
Feedback/ What to improve
After presenting we were given great feedback. Some of the feedback was on including a voice activation system that would include Siri or Amazon Alexa and allow the mirror to be voice activated. That would allow for anything ranging from asking questions to putting music. The next crucial feedback was the aesthetic. We could improve the frame and the way we have the ambient lights surrounding the mirror. One example that was given was putting a milky white sheet so you can't see the individual lights. The last and favorite piece of advice was adding a display that would allow for notes or affirmations. Moving forward those are some pieces that we would like to add to our prototype.
- Engmann, Nick. “Magic Mirror Module for Particle.Io Data.” Particle Projects, 11 May 2020, particle.hackster.io/nick-engmann/magic-mirror-module-for-particle-io-data-bbc5c0.
- josh_kilinc, and Instructables. “Smart Mirror.” Instructables, Instructables, 13 June 2022, www.instructables.com/Smart-Mirror-8/.
-Braun, Max. “Smarter Mirrors and How They’re Made.” Medium, OneZero, 27 July 2020, onezero.medium.com/smarter-mirrors-and-how-theyre-made-327997b9eff7.
-https://diotlabs.daraghbyrne.me/docs/working-with-data/webhooks/openmeteo_weather
Upon receiving some feedback from our demon, we realized that in order to make our design more interactive and user centered, we should try to display more information that is customizable. Because some people told us they would like to know more weather information, while others said that they wish to put a To Do list that they can review in the morning. I think having a function where users can text the particle to display the information on a second display screen would be really cool.
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Final Project: Smart Mirror "Connectivity Display and Ambient Lights"