You can work in groups of two on this assignment.

Pair Programming

It is strongly recommended that you use formal “pair programming”, where one person (the driver) types/creates and the other (the navigator) observes/assists. Moreover, you should alternate roles so each person takes on each role for a roughly equal amount of time. Remember that a spokesperson will be designated at checkout time, so both group members need to be comfortable presenting the work.


Decide if you will be working in a group or not before configuring a repository . If you will be working in a group, decide who will create the GitHub group and who will join it.

Follow the same basic process used in studios and previous assignments to create/join a group and download the resulting repository (with GitHub Desktop).

This time:

  1. Use the File > Add Project Folder... to add the garage controller project (just the GarageController sub-folder) to Particle Dev.
  2. When you’ve completed the Garage Controller, remove its project folder and add the Remote Control project folder (GarageRemote) to Particle Dev. (You may try working with them simultaneously, but if you run into problems compiling/deploying code, try to remove unneeded project folders from Particle Dev)
  3. When completely done with programming, be sure to answer the questions in the in the root folder.

The GitHub Link is:

Files in your repository:

The repository currently contains a few files:

  • contains some questions you need to complete when you’re done with the assignment
  • Garage Hardware files
    • GarageController/src/GarageController.ino Copy/paste the updated/completed work from the previous assignment.
    • GarageController/lib/GarageHardware/src/GarageHardwareProxy.cpp Copy/paste the updated/completed work from the previous assignment.
    • You should not add any extra functions in this file, but only edit the contents of the existing functions, leaving the function signature unchanged.
    • GarageController/lib/GarageHardware/src/GarageHardware.h: This contains the declarations for the Hardware API used by the real hardware. These represent a contract between the hardware team and you. DO NOT MODIFY THEM.
    • GarageController/lib/GarageHardware/src/GarageHardwareReal.cpp: This contains the definitions for the Hardware API for real hardware. DO NOT MODIFY THEM.
    • GarageController/lib/GarageHardware/ This contains the directions you need to follow to switch between the hardware checkout with the mini-garage and using your proxy hardware.
  • User Interface Files
    • ui/GarageApp.html is empty. Copy/paste code from the previous assignment.
    • ui/GarageApp.js is empty. Copy/paste code from the previous assignment.
    • ui/Garage.js is empty. Copy/paste code from the previous assignment.
    • ui/GarageModelTestStub.html is an HTML file that just includes the contents of Garage.js and the Particle API. It can be used to test Particle API calls and the garage model in the JavaScript console.
    • ui/resouces/particle/particle.min.js Particle’s JavaScript API. DO NOT MODIFY
  • Remote Control hardware files
    • GarageRemote/src/GarageRemote.ino is empty, but should be updated to include the implementation of your remote control.
  • documentation/ This contains a description of the files that should be included in the documentation directory when you’re done.

Your (Fifth) Assignment

DBI has decided they’d like you to complete the functionality of their first internet-enabled garage door opener prototype. They’d like the following features in the garage controller and UI:

  • They’d like the light to stay on for a configurable time before beginning to fade off. (They refer to this as the “auto-off” time)
  • They’d like to give users the ability to turn the light off/on.

In addition, they’d like you to develop a new product line and make it work with the garage controller prototype. They’d like to be able to sell physical Remote Controls that people could install in convenient locations. The Remote Controls should allow people to operate the Garage Door and Light when they are too far from the door’s button and also don’t want to open an app or access a webpage. The remotes will:

  • Include buttons to control garage door features
  • Include a screen (OLED) to see the state of the garage

Implementation Requirements

General requirements:
  • You must meet all previous assignment requirements.
  • All “buttons” for features should exhibit the same behavior, regardless of whether it is a physical button (on the garage or on a remote) or a UI button
    • Door buttons
      • Should start the door’s motion if it’s halted
      • Should stop the door’s motion if it’s moving
    • Light buttons
      • Should turn the light on if it’s off
      • Should turn the light off if it’s on
  • All UIs (OLED and webpage) should provide a clear indication of state:
    • Door opening
    • Door closing
    • Door stopped / fault (this can be shown in detail or all types of errors and faults can be depicted with a single message)
    • Light Status (on/off)
JavaScript/UI Requirements (Variation on Assignment 4 Requirements):
  • Data Communications Design:
    • The data communication features supported by Particle (e.g., variables, function calls, and event streams), should be used in appropriate ways.
    • Unnecessary polling of information from a remote system could use excessive data when this work is converted to a mobile app, so it is not allowed. (I.e., don’t use a JavaScript timer to repeatedly call functions on the Photon). This can usually be avoided by using a publish-subscribe model (Particle’s Event Streams)
  • Light Control:
    • Users should be able to turn the lights on/off from the UI
    • Users should be able to set the light’s maximum brightness from the UI
      • When the light is “on” it will be on at this maximum brightness. For example, if the “maximum” is set to 50% the light will never be on at full power. WHen the light comes on (either due to door motion or a light button) it will be on at this partial brightness. When it fades to off, it will start from this value.
      • The “minimum” value of maximum brightness should still be reasonably visible. That is, the users will only be allowed to pick from a range of values that are clearly “on”, but that have varying brightness.
    • Users should be able to configure the light auto-off time from the UI
      • Use 1s to 60s to simplify testing and demos
Controller Hardware Requirements (Additions to Assignment 4 Requirements):
  • Light Behavior:
    • The light should be at the configured “maximum” brightness whenever the door is moving. As soon as the door stops the light’s auto-off timer should start.
    • When the light is turned on, it should start at the configured “maximum” brightness.
    • The light will fade off over 5s after the auto-off time has elapsed.
    • The light should automatically fade off after the “auto-off” time regardless of how it was turned on. (There is no “enable” for the light’s auto-off)
    • If the light is on when a light button is hit, the light should turn off immediately (even if the door is in motion or if the light is fading off).
    • If the light is off when a light button is hit, the light should turn on and the auto-off timer should start. Example: If the “auto-off” time is 4 seconds and light is turned on (no door motion), the light should stay on at the configured “maximum” brightness for 4 seconds and then fade off over the remaining 5 seconds.
    • Fades always start at the configured “maximum” brightness and proceed to a complete off.
    • Toggling it while fading will make it turn off immediately.
    • Toggling it while it is off will make it turn on immediately and reset/restart the auto-off timer.
    • Changing the maximum brightness while the light is on should immediately change the brightness.
    • Changing the maximum brightness while the light is fading can be done at your discretion (the maximum setting should be changed, but it doesn’t have to impact the values used for the current fading)
Remote Hardware & Implementation Requirements :
  • Uses a Photon as the primary processor (this assignment uses both Photons)
  • Buttons should not appear to bounce. The approach you use for debouncing is at your discretion.
  • Includes an OLED screen that shows the garage state. It should clearly show:
    • Door state
    • Light state
  • Includes two buttons (or wires to simulate buttons):
    • One to toggle the door state
    • One to toggle the light state
  • The Remote should not interact with UIs in any way. It should be able to interact with the controller controller even if the UI isn’t opened/running.
  • When the remote starts it should somehow request state information (much like the webpage UI should).
  • Like the webpage UI, it should not allow the buttons to impact state until it receives valid state information.

Suggested Work Flow

  1. Review and revise your work from Assignments 1-4.
  2. Add support to the firmware (Photon) for the light features first.
  3. Test them using the online console or the options in the Particle menu.
  4. Update the UI to support the light features.
  5. Identify how you plan to have the remote interact with the garage (functions? variables? event streams?). Review Particle’s documentation as necessary.
  6. Add any additional support to the garage controller.
  7. Test any additions via the online console or Particle menu.
  8. Remove the Controller project’s folder from Particle Dev and add in the Remote project’s folder.
  9. Build an appropriate circuit.
  10. Include support for the OLED.
  11. Ensure that you can display information (for the state display) on the OLED.
  12. Update your sketch to acquire state from the cloud.
  13. Update your sketch to support the buttons.
  14. Clean up code, create circuit diagrams, and complete the
    • You need to include a diagram for the remote and the proxy hardware


  1. Use private event streams rather than public streams.
  2. Particle limits users to 4 streams.
  3. Photon’s can not easily call functions on other Photons, but they can communicate via Event Streams.
  4. Review the String class includes methods that may help you parts apart data. If data formats are excessively complex, consider using different formats in different streams. Devices with limited functionality may rely on simpler message types.
    • Test parsing in a simple sketch. You may try “publishing” dummy messages via the on-line conoles and have your sketch println() details of the parsing process.
  5. The OLED is an SD1306. The part should be available in Fritzing.

Artifacts that are Due

  • The documentation directory should contain up-to-date versions of:
    • State Machine Diagram
    • Fritzing circuit diagram for the garage controller proxy hardware
    • Fritzing circuit diagram of the remote control
  • A working circuits to demonstrate behavior.
  • A working UI to demonstrate behavior.
  • Completed versions of GarageController.ino, GarageHardwareProxy.cpp, GarageApp.html, GarageApp.js, Garage.js, and GarageRemote.ino
  • Completed

Tentative Rubric

UI Behavior (25 points)
  • Meeting all previous requirements: 10
  • UI support for light features: 15
Controller Hardware Behavior (30 points)
  • Meeting all previous requirements: 10
  • Support for light features: 10
  • Support for remote control features: 10
Remote Hardware Behavior (30 points)
  • Support for displaying state: 10
  • Support for operating door: 10
  • Support for operating light: 10
Best Practices (15 points)
  • Separate page HTML, CSS, and JavaScript files (5 points)
  • Code is non blocking / non-polling (5 points)
  • Code is easy to read and is properly commented (5 points)

Submission & Checkout

As outlined in the course policies, you must commit work to GitHub and demo it by class time on the due date for full credit.

You need to be prepared to demo and explain your work during your checkout as well as answer the questions in the (The final checklist may help verify that you are ready to demo)

Checkout and review will be done on a first-come-first-serve basis. If you aren’t done before class, you risk not being able to check out during class time. Work demoed after class time is considered late and will either not count as a grade or will consume late day coupons.