Introduction: Cloud Connected, Motion Activated, Digital Photo Frame
This is a really fun and easy project I worked on with my son. I will show how you can build this as simple or as complex as you want.
For this project, we used an old Amazon Fire Stick Gen1 (also tested with a Gen2) and a 23" HDMI monitor (any size will work). This also includes an Arduino, relay module, and PIR sensor for the motion activation. The Digital photo frame displays a slideshow of pictures from Amazon Photos. This picture frame is motion activated, so it will shut off the display when no motion is detected for a period of time.
Step 1: Setting Up - Proof of Concept
In its simplest form, this is just an old Amazon Fire Stick connected via HMDI to a monitor. To get started, all we did was plug the Fire Stick into the back of the monitor and power the stick. Once the device boots up we can open Amazon Photos to view all of the pictures. In Amazon Photos we have created a new album called "Photo Frame". Now on the Fire Stick, we can easily browse to this album and start a slideshow.
At this point, you have a working Photo Frame and could stop here but please continue to read more to see how you can add even more features to make this the perfect Photo Frame for you!
Step 2: Automating With the Arduino
The Ardunio receives input from the PIR sensor when motion is detected. If no motion is detected for a given period of time then the Ardunio sends a signal to the relay module to switch off the power. Likewise, if the power is already off and the Arduino receives input from the PIR sensor then it will switch the relay module on.
Here is a diagram of the electronics used in this project. As you can see this is a very simple build. The Arduino PIN 8 sends the signal to the Relay Module to turn on/off. The Arduino PIN 3 receives the signal from the PIR sensor. The monitor and lights are plugged into the outlet so when no motion is detected these are powered off. The Arduino and FireStick are powered from different outlets (not shown here) and always on. The slideshow is always running even when the monitor is powered off. This way, the FireStick will show immediately after the monitor powers back on and not need to be boot up.
Here is a list of the electronic components used in this build:
Step 3: Review the Code
Now let's review the Arduino Sketch. I will break this down into four parts and explain each section. See the attached file for all the code, including additional comments.
SECTION I of IV
In this section, we will define the variables and PINs used later in the code. If you are building this project, the only thing you need to change is the TIMEOUT variable. This will define how long "no motion" is detected before the screen is powered off. Here you can see it is set for 30 minutes. You may also need to change the PINs if you are using different digital pins on the Arduino.
// defined shut off period after no motion is detected (in minutes) int timeout = 30; //the time we give the sensor to calibrate (10-60 secs according to the datasheet) int calibrationTime = 30; //the time when the sensor outputs a low impulse long unsigned int lowIn; //convert timeout to milliseconds long unsigned int intNoMovementTimeout = timeout * 60000; boolean RelayOff = true; boolean getLowTime; int pirPin = 3; //the digital pin connected to the PIR sensor's output int relayPin = 8; //the digital pin connected to the relay module
SECTION II of IV
Here we will define the "setup" routine which runs when the Arduino first powers on. First, we define the Serial output used for debugging. Then we define the input or output for the PINs used (PIR sensor is input and Relay is Output). Next, we run through a 'calibration' which you can watch on the serial output.
void setup(){<br> Serial.begin(9600); pinMode(pirPin, INPUT); pinMode(relayPin, OUTPUT); digitalWrite(pirPin, LOW); //give the sensor some time to calibrate Serial.print("calibrating sensor "); for(int i = 0; i < calibrationTime; i++){ Serial.print("."); delay(1000); } Serial.println(" done"); Serial.println("SENSOR ACTIVE"); delay(50); }
SECTION III of IV
Sections III and IV are both inside of the "VOID LOOP()" which will continuously loop over and over while the Arduino is powered on. In this section, motion is detected from the PIR which sets the pirPIN input to HIGH. If the Relay Module is currently turned switched OFF then this will turn the Relay on by setting its relayPIN to HIGH. Otherwise, if the Relay Module is currently switched ON then nothing changes.
if(digitalRead(pirPin) == HIGH){ //if motion is detected if(RelayOff){ //and if the Relay is switched OFF //makes sure we wait for a transition to LOW before any further output is made: RelayOff = false; //turn off the 'Relay Off' variable digitalWrite(relayPin, HIGH); //set the state of the relay pin to 'ON' Serial.print("motion detected at "); Serial.print(millis()/1000); Serial.println(" sec"); Serial.println("motion was detected while relay was switched OFF; now haved switched ON"); delay(50); //pause for X milliseconds } else { Serial.println("motion detected but the relay is already switched ON"); delay(5000); } getLowTime = true; //turn on the 'Get Low Time' variable }
SECTION IV of IV
The final section is the second half of the VOID LOOP function. In this section, motion is not detected so the pirPIN is LOW. We don't want this to power off immediately after no motion is detected but instead only power off after motion isn't detected for a defined number of minutes. The first half of this section is when no motion is detected but we haven't exceeded our timeout yet. In the second half, no motion is detected and the timeout period has exceeded. This then sends a signal to the relay to switch the power off.
if(digitalRead(pirPin) == LOW){ <br> //When PIR first detects no movement record the time if(getLowTime){ lowIn = millis(); //save the time of the transition from high to LOW getLowTime = false; //make sure this is only done at the start of a LOW phase Serial.print("Recording time when 'no motion' was first detected - "); //output Serial.println(lowIn / 1000); } //Only turn off relay if the PIR Sensor has seen no movement for more than the defined 'No Movement Timeout' time if(!RelayOff && millis() - lowIn > intNoMovementTimeout){ RelayOff = true; //turn on the 'Relay Off' variable digitalWrite(relayPin, LOW); //set the state of the relay pin to 'OFF' Serial.print("Turning off relay now. Motion ended at "); //output Serial.print((millis() - intNoMovementTimeout)/1000); Serial.println(" sec"); delay(50); //pause for X milliseconds } }
Step 4: Powering Devices
Here we used a small four outlet power strip to power all the four devices (Monitor, Lights, Arduino, and Fire Stick).
For this project, I shorted the length of the cable coming out of the strip but that is not necessary. With the power stip opened, there are three metal rails to conduct electricity between all of the outlets. I cut one of the metal rails (not the ground) in half and soldered one electrical wire to each half coming out the middle of the strip (drilled a small hole on side of power strip). The two electrical wires were then connected to the relay module (the connection order doesn't matter). This allows the relay module to create a physical break in the line between the two halves of the rail, cutting off power to the last two outlets.
Step 5: Building the Frame
I will not go into specifics on how I built the frame as this is going to be different for everyone depending on the monitor and parts you use. Basically, you can see from the images, we built a box about 2 1/2" deep to hold the monitor and other electronics. Then I built the frame to fit over the top of the box. We painted my box white and the inside black.
The screen we used didn't have much of a bezel around the sides of the screens so I spent too much time trying to exactly line this up so it didn't overlap the screen. Now that it is up and in use, I realize a small overlap of the screen would have been fine as most pictures don't go edge to edge and even if they do lose a little at the very edges wouldn't matter.
We also added a french cleat on the wall to hang this frame. This makes it very easy to hang and take down if you need to make any adjustments.
Step 6: Accessorizing
Now we have the electronics working and the frame built. We could stop here but why not make it stand out even more? We decided to add a LED light strip around the back of the frame facing the wall to make this frame glow. These lights change color with a remote control and plugin to the electrical outlet via a USB adapter. You can set these to a lot of different colors or have it cycle through pre-programmed patterns. They work very well. When these lights power on it remembers the color or pattern you previously set so you don't have to and change this every time it goes to sleep.
I could have used a programmable WS2812B LED strip instead of this one and then controlled the patterns via the Arduino. That will have to be in version 2.0.
For more information on using LED strip lights, check out the Instructable class "LEDS AND LIGHTING CLASS". I have not gone through this completely but just a quick pass and it seems to be a really good starting point.
Step 7: Finishing Touches
Finally, everything is working great. Now I really should be calling it quits but I wanted to add two more features. First, I wanted to add a switch to power off the frame when we don't want it on. Second, I wanted to add a switch to disable the motion activation so the frame will not go to sleep.
To power off the frame, I simply removed the switch from the power strip and soldered on some longer cables allowing me to extend this to the top of the box. When I turn this off it does kill the power to the entire power strip, including the Arduino and Fire Stick.
To stop the motion detection, I put a small rocker switch in the middle of the ground wire between the Arduino and the PIR Sensor. When this is switched off (circuit is open) then the Arduino is continuously getting a signal from the sensor, even where no motion is present.
See the attached diagram for an illustration of where to add these switches.
Step 8: What I Learned Along the Way
There were a few detours along the way which I had to work around. Hopefully, you can learn from my experiences so your project goes smoothly.
- TEST, TEST, TEST.....and then assemble. At first, I thought this was so simple I didn't even bother fully testing everything before I built it. I started by building the box and frame about the monitor. I had an old unused monitor but this only had VGA and DVI ports for video. I thought I could use an HDMI to DVI adapter but this would not work. After researching the problem, it seems because of the encryption on the Fire Stick this will not function this way so I had to find a different monitor. UGG!! Needless to say, I had to scrap that first box and frame to start over.
- After I did have this working on the First Stick, I went to SETTINGS -> DISPLAY and configured this to go to the slideshow automatically after five minutes of inactivity. This worked well, and the screensaver came on as expected, except after about 20 minutes the signal from the stick would stop. I wasn't sure why this was timing out and I couldn't find a way to stop this. After banging my head for a while, I finally figured out I need to start this from the Amazon Photos app instead and not use the screensaver under Display Settings.
- When we upload new picture to Amazon Photos we need to stop the screensaver and restart this again to see the newly uploaded images.
Step 9: In Conclusion
In the end, this turned out to be a fun project and looks great in our living room now. We added a lot of features to this but you certainly could make this very simple. My son and I learned a lot about controlling the relay module and PIR Sensor with the Arduino. We can see a lot of other projects using these same concepts (motion activated lights, motion activated TV or appliances).
Thanks for checking this out. Please leave a comment and share if you do tackle this project.
Keep building,
Chris